0Pricing
Java Academy · Aula

Serialização Personalizada: writeObject e readObject

Substitua writeObject e readObject para criptografia, compactação ou tratamento personalizado de campos.

Serialização Personalizada: writeObject e readObject é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.

Quando a Serialização Padrão Não é Suficiente

A serialização padrão salva todos os campos que não são transient exatamente como estão. Às vezes, você precisa de criptografia, compactação ou uma representação diferente. É nesse ponto que entram os ganchos writeObject / readObject.

Declarando writeObject

Adicione um método private void writeObject(ObjectOutputStream oos). Java o chamará em vez do mecanismo padrão. Você controla exatamente o que será gravado.

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject(); // write non-transient fields normally
    oos.writeUTF(encrypt(this.secret)); // write encrypted secret
}

Declarando readObject

Adicione um método private void readObject(ObjectInputStream ois). Java o chamará durante a desserialização. Você deve ler os dados exatamente na mesma ordem em que os gravou.

private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    ois.defaultReadObject(); // restore non-transient fields
    this.secret = decrypt(ois.readUTF()); // decrypt and restore
}

A Ordem é Importante

Tudo o que você gravar em writeObject deverá ser lido novamente na mesma ordem em readObject. Uma ordem incompatível causa StreamCorruptedException.

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.writeInt(version);
    oos.writeUTF(data);
}
private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    this.version = ois.readInt();  // same order
    this.data    = ois.readUTF();
}

Compactando Dados Durante a Serialização

Envolva o fluxo com GZIPOutputStream dentro de writeObject para compactar campos grandes e, em seguida, use GZIPInputStream dentro de readObject para descompactá-los.

private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try (GZIPOutputStream gz = new GZIPOutputStream(bos)) {
        gz.write(largePayload.getBytes());
    }
    oos.writeObject(bos.toByteArray());
}

O Gancho readResolve

readResolve() é chamado após a desserialização. Retorne um objeto substituto — isso é útil para instâncias únicas e enumerações, garantindo que exista apenas uma instância após a desserialização.

public class AppConfig implements Serializable {
    private static final AppConfig INSTANCE = new AppConfig();
    private AppConfig() {}
    public static AppConfig getInstance() { return INSTANCE; }
    private Object readResolve() { return INSTANCE; } // return singleton
}

O Gancho writeReplace

writeReplace() é chamado antes da serialização. Retorne um objeto diferente para que ele seja serializado no lugar do original — isso é útil para padrões de proxy e substitutos de serialização.

private Object writeReplace() {
    return new UserProxy(this.id); // serialize a lightweight proxy
}

Validando Campos em readObject

Você pode adicionar lógica de validação dentro de readObject para rejeitar dados inválidos ou adulterados como parte de uma estratégia de defesa em profundidade.

private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    if (age < 0 || age > 150) {
        throw new InvalidObjectException("Invalid age: " + age);
    }
}

Lidando com Alterações de Versão

Use um campo de versão em writeObject para que readObject possa lidar adequadamente com os formatos antigo e novo durante as migrações.

private static final int SERIAL_VERSION = 2;
private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.defaultWriteObject();
    oos.writeInt(SERIAL_VERSION);
    if (SERIAL_VERSION >= 2) oos.writeUTF(email); // new field
}
private void readObject(ObjectInputStream ois)
        throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    int v = ois.readInt();
    if (v >= 2) this.email = ois.readUTF();
}

Padrão de Proxy de Serialização

Uma abordagem robusta é escrever uma classe interna estática privada que capture o estado mínimo e, em seguida, usar writeReplace para gravar o proxy e seu readResolve para reconstruir o objeto original.

Considerações de Desempenho

A serialização personalizada adiciona sobrecarga de chamadas de método, mas pode reduzir significativamente o tamanho da carga útil. Faça medições de desempenho antes de otimizar; use Externalizable para obter o máximo de controle.

Verificação Rápida

O que deve ser verdade sobre a ordem em writeObject e readObject?

Recapitulação

Substitua writeObject / readObject para usar criptografia, compactação ou formatos personalizados. Use readResolve para instâncias únicas. Sempre leia na mesma ordem em que gravou.

Perguntas Frequentes

A aula “Serialização Personalizada: writeObject e readObject” é grátis?

Sim — o texto completo de “Serialização Personalizada: writeObject e readObject” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.

O que vou aprender em “Serialização Personalizada: writeObject e readObject”?

Substitua writeObject e readObject para criptografia, compactação ou tratamento personalizado de campos. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Java Academy?

Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Serialização Personalizada: writeObject e readObject”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Java Academy?

Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Fundamentos da Serialização em Java
  2. Campos transient e serialVersionUID
  3. Serialização Personalizada: writeObject e readObject
  4. Alternativas Modernas: JSON e Protocol Buffers
← Voltar para Java Academy