Trabalhamos intensamente com serialização e ter que especificar a tag Serializable em cada objeto que usamos é meio que um fardo. Especialmente quando é uma aula de terceiros que não podemos realmente mudar.
A questão é: já que Serializable é uma interface vazia e o Java fornece serialização robusta quando você adiciona implements Serializable
- por que eles não tornaram tudo serializável e é isso?
o que estou perdendo?
java
serialization
Yoni Roit
fonte
fonte
Respostas:
A serialização está repleta de armadilhas. O suporte de serialização automática deste formulário torna a parte interna da classe da API pública (é por isso que o javadoc fornece as formas persistentes de classes ).
Para persistência de longo prazo, a classe deve ser capaz de decodificar essa forma, o que restringe as alterações que você pode fazer no design da classe. Isso quebra o encapsulamento.
A serialização também pode levar a problemas de segurança. Por ser capaz de serializar qualquer objeto ao qual tenha uma referência, uma classe pode acessar dados que normalmente não seria capaz (analisando os dados de byte resultantes).
Existem outros problemas, como a forma serializada das classes internas não ser bem definida.
Tornar todas as classes serializáveis exacerbaria esses problemas. Confira Effective Java Second Edition , em particular o Item 74: Implementar Serializable judiciosamente .
fonte
Acho que tanto o pessoal do Java quanto do .Net erraram desta vez, teria sido melhor tornar tudo serializável por padrão e apenas precisar marcar as classes que não podem ser serializadas com segurança.
Por exemplo, em Smalltalk (uma linguagem criada nos anos 70), todo objeto é serializável por padrão. Não tenho ideia de por que esse não é o caso em Java, considerando o fato de que a grande maioria dos objetos é segura para serializar e apenas alguns deles não.
Marcar um objeto como serializável (com uma interface) não torna esse objeto magicamente serializável, ele era serializável o tempo todo , só que agora você expressou algo que o sistema poderia ter encontrado por conta própria, então não vejo um bom motivo para serialização sendo do jeito que está agora.
Acho que foi uma má decisão dos designers ou a serialização foi uma reflexão tardia, ou a plataforma nunca estava pronta para fazer a serialização por padrão em todos os objetos de forma segura e consistente.
fonte
Serializable
truque é apenas mais uma decisão errada que foi tomada há uma ou duas décadas, e mais um acréscimo ao aborrecimento ao lidar com java puro, como algumas falhas no processamento de coleção e string na biblioteca padrão. Felizmente existe Kryo, mas é uma dependência e é preciso encontrá-lo primeiro. É assim que a serialização interna deveria ter sido feita.Nem tudo é genuinamente serializável. Considere uma conexão de soquete de rede, por exemplo. Você poderia serializar os dados / estado de seu objeto de soquete, mas a essência de uma conexão ativa seria perdida.
fonte
implements NotSerializable
:)A principal função do Serializable em Java é tornar, por padrão, todos os outros objetos não serializáveis. A serialização é um mecanismo muito perigoso, especialmente em sua implementação padrão. Conseqüentemente, como a amizade em C ++, ele está desativado por padrão, mesmo que custe um pouco para tornar as coisas serializáveis.
A serialização adiciona restrições e problemas potenciais, uma vez que a compatibilidade da estrutura não é garantida. É bom que esteja desativado por padrão.
Tenho que admitir que vi muito poucas classes não triviais onde a serialização padrão faz o que eu quero. Especialmente no caso de estruturas de dados complexas. Portanto, o esforço que você gastaria para tornar a classe serializável de maneira adequada diminui o custo de adicionar a interface.
fonte
Para algumas classes, especialmente aquelas que representam algo mais físico como um arquivo, um soquete, um thread ou uma conexão de banco de dados, não faz absolutamente nenhum sentido serializar instâncias. Para muitos outros, a serialização pode ser problemática porque destrói as restrições de exclusividade ou simplesmente força você a lidar com instâncias de diferentes versões de uma classe, o que você pode não querer.
Indiscutivelmente, poderia ter sido melhor tornar tudo Serializável por padrão e tornar as classes não serializáveis por meio de uma palavra-chave ou interface de marcador - mas então, aqueles que deveriam usar essa opção provavelmente não pensariam sobre isso. Do jeito que está, se você precisar implementar Serializable, será informado por uma Exceção.
fonte
Acho que o pensamento era garantir que você, como programador, saiba que seu objeto pode ser serializado.
fonte
Aparentemente, tudo era serializável em alguns designs preliminares, mas por questões de segurança e correção, o design final acabou como todos sabemos.
Fonte: por que as classes devem implementar Serializable para serem gravadas em um ObjectOutputStream? .
fonte
Ter que declarar explicitamente que as instâncias de uma determinada classe são serializáveis, a linguagem força você a pensar se deve permitir isso. Para objetos de valor simples, a serialização é trivial, mas em casos mais complexos você precisa realmente pensar sobre as coisas.
Contando apenas com o suporte de serialização padrão da JVM, você se expõe a todos os tipos de problemas desagradáveis de versão.
Exclusividade, referências a recursos 'reais', temporizadores e muitos outros tipos de artefatos NÃO são candidatos para serialização.
fonte
Leia isto para entender a Interface serializável e porque devemos fazer apenas algumas classes serializáveis e também devemos tomar cuidado onde usar a palavra-chave transiente no caso de querermos remover alguns campos do procedimento de armazenamento.
http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/
fonte
Bem, minha resposta é que isso não é uma boa razão. E pelos seus comentários, posso ver que você já aprendeu isso. Outras linguagens tentam serializar tudo o que não pula em uma árvore depois que você conta até 10. Um objeto deve ser serializável por padrão.
Então, o que você basicamente precisa fazer é ler todas as propriedades de sua classe de terceiros. Ou, se essa for uma opção para você: descompilar, colocar a maldita palavra-chave lá e recompilar.
fonte
Existem algumas coisas em Java que simplesmente não podem ser serializadas porque são específicas do tempo de execução. Coisas como streams, threads, runtime, etc. e até mesmo algumas classes GUI (que estão conectadas ao SO subjacente) não podem ser serializadas.
fonte
Embora eu concorde com os pontos apresentados em outras respostas aqui, o verdadeiro problema é com a desserialização: se a definição da classe mudar, então há um risco real de que a desserialização não funcione. Nunca modificar campos existentes é um compromisso muito importante para o autor de uma biblioteca! Manter a compatibilidade da API já é uma tarefa árdua.
fonte
Uma classe que precisa ser persistida em um arquivo ou outra mídia deve implementar a interface Serializable, para que a JVM possa permitir que o objeto de classe seja serializado. Por que a classe Object não é serializada, nenhuma das classes precisa implementar a interface, afinal a JVM serializa a classe apenas quando eu uso ObjectOutputStream, o que significa que o controle ainda está em minhas mãos para permitir que a JVM seja serializada.
A razão pela qual a classe Object não é serializável por padrão é o fato de que a versão da classe é o principal problema. Portanto, cada classe interessada em serialização deve ser marcada explicitamente como serializável e fornecer um número de versão serialVersionUID.
Se serialVersionUID não for fornecido, obteremos resultados inesperados ao desserializar o objeto, é por isso que a JVM lança InvalidClassException se serialVersionUID não corresponder. Portanto, cada classe deve implementar a interface Serializable e fornecer serialVersionUID para garantir que a classe apresentada nas duas extremidades seja idêntica.
fonte