Atenção: Com as evoluções do Java e práticas modernas, existem alternativas mais seguras e eficientes para lidar com serialização/desserialização. Mas como estamos estudando o livro vamos considerar para aprender. VER NO TÓPICO FINAL SOBRE SERIALIZAÇÃO
1. Problema da forma serializada padrão
- A forma serializada padrão pode tornar impossível substituir uma implementação descartável.
- Muitas classes da biblioteca Java, como BigInteger, sofreram com essa limitação.
- Deve-se avaliar se a forma serializada padrão é apropriada em termos de flexibilidade, desempenho e correção.
2. Quando a forma serializada padrão é aceitável?
- Quando a representação física do objeto é idêntica ao seu conteúdo lógico.
- Exemplo: uma classe Name com três String (sobrenome, primeiro nome e nome do meio).
3. Problemas ao usar a forma serializada padrão quando a representação física difere do conteúdo lógico
- Acopla a API pública à implementação interna, impedindo mudanças futuras.
- Aumenta o consumo de espaço, armazenando detalhes desnecessários.
- Pode ser ineficiente em tempo de execução, devido a percursos desnecessários no grafo do objeto.
- Pode causar overflow de pilha, especialmente em listas encadeadas grandes.
4. Exemplo: Serialização de uma lista encadeada (StringList)
- A forma serializada padrão armazenaria todos os nós e links internos, o que é ineficiente.
- Solução: armazenar apenas o número de elementos e suas String associadas.
- Isso reduz o espaço ocupado e melhora a performance da serialização.
5. Implementação de uma forma serializada customizada
- Criar os métodos writeObject e readObject para controlar a serialização.
- Utilizar o modificador transient para evitar serializar detalhes desnecessários.
- Sempre chamar defaultWriteObject e defaultReadObject para garantir compatibilidade futura.
- Documentar a API serializada com @serial (campos) e @serialData (métodos).
6. Problema ainda maior com tabelas hash
- A posição dos elementos depende do código hash da chave, que pode mudar entre execuções.
- Serializar a estrutura física de uma tabela hash poderia corromper suas invariantes.
- Solução: armazenar apenas os pares chave-valor e recriar a estrutura na desserialização.
7. Regras gerais para serialização eficiente
- Declarar como transient qualquer campo que não faça parte do estado lógico do objeto.
- Evitar serializar campos derivados, cujo valor pode ser recalculado.
- Evitar serializar ponteiros para estruturas nativas da JVM.
Conclusão
- A forma serializada padrão deve ser aceita apenas se for adequada ao estado lógico do objeto.
- Para maior controle, use uma forma serializada customizada, garantindo eficiência e flexibilidade.
- Isso evita problemas futuros com manutenção, desempenho e compatibilidade da API serializada.
Exemplos do livro:
.