1. Serialização binária em Java
Serialização binária — é o mecanismo padrão do Java pelo qual um objeto é transformado em um fluxo de bytes de forma máxima e rapidamente. Para isso, utilizam-se as classes ObjectOutputStream e ObjectInputStream. O arquivo resultante é um conjunto de bytes que não é destinado à leitura humana.
Ela é chamada de binária porque tudo é serializado em formato “bruto”: números, strings, arrays e até referências entre objetos viram bytes. É como uma mala bem compactada: eficiente e rápida, mas sem instruções não é óbvio onde está cada coisa.
Como isso funciona em Java?
Suponha que temos a classe User:
import java.io.Serializable;
public class User implements Serializable {
private String name;
private int age;
// Construtor, getters e setters
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
}
Serialização para arquivo binário
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
User user = new User("Vasya", 30);
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.bin"))) {
out.writeObject(user);
System.out.println("Objeto User serializado para o arquivo user.bin");
} catch (Exception e) {
e.printStackTrace();
}
Desserialização de arquivo binário
import java.io.FileInputStream;
import java.io.ObjectInputStream;
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.bin"))) {
User loadedUser = (User) in.readObject();
System.out.println("Lido do arquivo: " + loadedUser.getName() + ", " + loadedUser.getAge());
} catch (Exception e) {
e.printStackTrace();
}
Atenção: se você abrir o arquivo user.bin em um editor de texto, verá algo como: ¬í sr ... — isso é normal, é assim mesmo!
Vantagens da serialização binária
- Compacidade e velocidade. A gravação e a leitura são realizadas o mais rápido possível, sem “enfeites” desnecessários.
- Todos os campos do objeto são preservados, incluindo objetos aninhados (se eles também forem serializáveis via Serializable).
- Fácil de usar para cache interno ou para transferência entre programas Java.
Desvantagens
- Ilegibilidade. Uma pessoa não conseguirá “espiar” o conteúdo e entender o que há ali.
- Vinculação rígida à versão da classe. Alterar a estrutura (adicionar/remover campos) pode “quebrar” a leitura de arquivos antigos.
- Problemas de compatibilidade entre diferentes versões de Java e JVM.
- Não é adequado para troca com outras linguagens de programação.
- Segurança: desserializar dados de fontes não confiáveis é um caminho direto para vulnerabilidades.
2. Formatos de serialização em texto: JSON, XML e outros
A serialização binária é boa para uso interno, mas muitas vezes é preciso transmitir dados entre diferentes linguagens (Java, JavaScript, Python) ou armazená-los em formato legível — útil para configurações, logs e APIs. Para isso, usam-se formatos de texto: JSON, XML, YAML, CSV etc.
JSON — o mais popular
JSON (JavaScript Object Notation) — formato compacto e legível. Exemplo de objeto User serializado:
{
"name": "Vasya",
"age": 30
}
No Java, para trabalhar com JSON, as bibliotecas mais usadas são: Jackson (a mais popular), Gson, além de Moshi, JSON-B etc.
XML — o velho amigo do programador
XML (Extensible Markup Language) — mais “verboso”, porém formal e rigoroso.
<User>
<name>Vasya</name>
<age>30</age>
</User>
Para XML no Java, costuma-se usar a biblioteca padrão JAXB (ou a mais antiga XStream).
YAML, CSV e outras
- YAML — parecido com JSON, porém mais conciso; é mais usado para configs do que para serialização de objetos complexos.
- CSV — bom para tabelas “planas”, mas pouco adequado para estruturas aninhadas.
- Existem formatos para todos os gostos, mas no Java os mais usados são JSON e XML.
3. Comparação de formatos: quando usar o quê?
| Formato | Legibilidade | Compacidade | Velocidade | Compatibilidade | Quando usar |
|---|---|---|---|---|---|
| Binário | Não | ++ | ++ | Apenas Java | Cache interno, salvamento rápido entre JVMs |
| JSON | Sim | + | + | Qualquer linguagem | APIs REST, integração com serviços externos, configurações |
| XML | Sim | - | - | Qualquer linguagem | Integração, esquemas rigorosos, sistemas legados |
- Binário — escolha para uso interno, quando não é necessária a troca com sistemas externos e a máxima performance é importante.
- JSON — a melhor escolha para integração com aplicações web, clientes móveis e APIs REST, além de armazenamento de configurações.
- XML — necessário em esquemas rigorosos e integração com soluções “corporativas”.
Importante! A serialização binária é apropriada apenas para transferência de dados entre programas Java e, mesmo assim, é mais seguro usá-la entre programas da mesma versão. Formatos de texto como JSON e XML são mais universais: adequados para troca de dados entre diferentes linguagens e plataformas, tornando a informação legível e portável.
4. Prática: serialização em formatos binário e de texto
Serialização binária (ObjectOutputStream/ObjectInputStream)
Já vimos acima, mas vamos repetir para fixar:
// Serialização
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("user.bin"))) {
out.writeObject(user);
}
// Desserialização
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("user.bin"))) {
User loadedUser = (User) in.readObject();
}
Serialização em JSON com Jackson (resumo)
Para trabalhar com Jackson, é preciso adicionar suas bibliotecas ao projeto. Vamos estudar Maven e Gradle mais adiante; por enquanto, é possível adicionar os JARs manualmente. Exemplo de dependência para o Maven:
<!-- Maven -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
Exemplo de serialização/desserialização:
import com.fasterxml.jackson.databind.ObjectMapper;
User user = new User("Vasya", 30);
ObjectMapper mapper = new ObjectMapper();
try {
// Serialização para String
String json = mapper.writeValueAsString(user);
System.out.println(json); // {"name":"Vasya","age":30}
// Serialização para arquivo
mapper.writeValue(new File("user.json"), user);
// Desserialização de String
User loadedUser = mapper.readValue(json, User.class);
// Desserialização de arquivo
User loadedFromFile = mapper.readValue(new File("user.json"), User.class);
} catch (Exception e) {
e.printStackTrace();
}
O arquivo JSON pode ser aberto em qualquer editor de texto, o que torna os dados fáceis de ler e portáveis entre diferentes aplicações e linguagens.
5. Quando usar cada formato: conselhos práticos
- Cache interno, arquivos temporários, gravação/leitura rápidas entre programas Java: use a serialização binária padrão. Mas lembre-se da compatibilidade de versões!
- Integração com serviços externos, armazenamento de configurações, integração com o front-end: use JSON (Jackson, Gson).
- Integração com sistemas “corporativos” em que é necessário um esquema rigoroso: XML (JAXB).
- É necessário que uma pessoa possa abrir e ler o arquivo: JSON ou XML, mas não o formato binário.
6. Erros comuns ao trabalhar com formatos de serialização
Erro nº 1: tentar serializar um objeto com campos não serializáveis. Se sua classe tiver um campo que não implementa Serializable (por exemplo, um stream ou uma conexão com o BD), a serialização binária lançará um erro. Para JSON isso não é tão crítico, mas com tipos “não padrão” também podem ocorrer problemas.
Erro nº 2: abrir um arquivo binário em um editor de texto e se assustar. Isso é normal! Arquivos binários não são destinados à leitura humana.
Erro nº 3: alterar a estrutura da classe e os arquivos binários antigos deixam de ser lidos. A serialização binária é sensível a mudanças na estrutura da classe — frequentemente ocorre InvalidClassException. Em JSON/XML, isso é menos crítico: campos desconhecidos geralmente são ignorados ou recebem valores padrão.
Erro nº 4: usar serialização binária para integração com sistemas externos. Isso não vai funcionar: o formato binário é entendido apenas pelo Java e, ainda assim, quando as versões coincidem.
Erro nº 5: esquecer de adicionar as anotações necessárias para JSON/XML. Algumas bibliotecas exigem anotações como @JsonProperty, @XmlElement; caso contrário, a serialização/desserialização pode não funcionar como o esperado.
Erro nº 6: não verificar se todos os objetos aninhados são serializáveis. Para a serialização binária, isso é um problema frequente; para JSON também, se o modelo tiver tipos complexos.
GO TO FULL VERSION