Por que Java precisa de interface Serializable?

Nós trabalhamos fortemente com a serialização e ter que especificar a tag Serializable em todos os objects que usamos é uma espécie de carga. Especialmente quando é uma aula de terceiros que não podemos mudar.

A questão é: desde Serializable é uma interface vazia e Java fornece serialização robusta, uma vez que você adiciona implements Serializable – por que eles não fizeram tudo serializável e é isso?

o que estou perdendo?

Serialização é repleta de armadilhas. O suporte de serialização automática deste formulário torna a parte interna da class parte da API pública (é por isso que o javadoc fornece as formas persistentes de classs ).

Para persistência de longo prazo, a class deve ser capaz de decodificar esse formulário, o que restringe as alterações que você pode fazer no design de classs. Isso quebra o encapsulamento.

A serialização também pode levar a problemas de segurança. Por ser capaz de serializar qualquer object para o qual tenha uma referência, uma class pode acessar dados que normalmente não seriam capazes (analisando os dados de byte resultantes).

Existem outros problemas, como a forma serializada de classs internas que não estão bem definidas.

Tornar todas as classs serializáveis ​​exacerbaria esses problemas. Confira o Effective Java Second Edition , em particular o Item 74: Implementar Serializable criteriosamente .

Acho que tanto o Java quanto o .Net erraram desta vez, teria sido melhor tornar tudo serializável por padrão e só precisar marcar as classs que não podem ser serializadas com segurança.

Por exemplo, em Smalltalk (uma linguagem criada nos anos 70), todo object é serializável por padrão. Eu não tenho idéia de por que isso não é o caso em Java, considerando o fato de que a grande maioria dos objects é segura para serializar e apenas alguns deles não são.

Marcar um object como serializável (com uma interface) não torna magicamente esse object 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 nenhuma boa razão para serialização sendo do jeito que é agora.

Eu acho que ou foi uma decisão ruim feita por designers ou serialização foi uma reflection tardia, ou a plataforma nunca foi pronta para fazer serialização por padrão em todos os objects com segurança e consistência.

Nem tudo é genuinamente serializável. Tome uma conexão de soquete de rede, por exemplo. Você poderia serializar os dados / estado do seu object de soquete, mas a essência de uma conexão ativa seria perdida.

O principal papel do Serializable em Java é realmente tornar, por padrão, todos os outros objects não serializáveis. Serialização é um mecanismo muito perigoso, especialmente em sua implementação padrão. Portanto, como a amizade em C ++, ela é desativada por padrão, mesmo que seja um pouco custoso tornar as coisas serializáveis.

A serialização adiciona restrições e possíveis problemas, pois a compatibilidade da estrutura não é assegurada. É bom que esteja desativado por padrão.

Tenho que admitir que vi poucas classs não triviais em que a serialização padrão faz o que eu quero. Especialmente no caso de estruturas de dados complexas. Assim, o esforço que você gastaria para tornar a class serializável anula o custo de adicionar a interface.

Para algumas classs, especialmente aquelas que representam algo mais físico, como uma conexão File, Socket, Thread ou DB, 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 class, o que talvez você não queira.

Indiscutivelmente, poderia ter sido melhor fazer tudo Serializable por padrão e tornar as classs não serializáveis ​​através de uma interface de palavra-chave ou 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, você será informado assim por uma exceção.

Eu acho que o objective era ter certeza de que você, como programador, sabia que seu object seria serializado.

Aparentemente, tudo foi serializado em alguns projetos preliminares, mas por questões de segurança e correção, o design final acabou como todos nós sabemos.

Fonte: Por que as classs devem implementar Serializable para serem gravadas em um ObjectOutputStream? .

Ter que declarar explicitamente que instâncias de uma determinada class são Serializáveis, a linguagem obriga a pensar se você deve permitir isso. Para objects de valores simples, a serialização é trivial, mas em casos mais complexos você precisa realmente pensar nas coisas.

Confiando apenas no suporte de serialização padrão da JVM, você se expõe a todos os tipos de problemas de versão desagradáveis.

Exclusividade, referências a resources ‘reais’, timeres e muitos outros tipos de artefatos NÃO são candidatos para serialização.

Leia isto para entender a Interface Serializável e porque devemos fazer apenas algumas classs Serializáveis ​​e também teremos o cuidado de usar a palavra-chave temporária caso desejemos remover alguns campos do procedimento de armazenamento.

http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/

Bem, minha resposta é que isso não tem um bom motivo. E de seus comentários, posso ver que você já aprendeu isso. Outras linguagens tentam felizmente serializar tudo o que não salta em uma tree depois de você ter contado 10. Um Objeto deve ser serializável por padrão.

Então, o que você basicamente precisa fazer é ler todas as propriedades de sua class de terceiros. Ou, se for uma opção para você: decompile, coloque a maldita palavra-chave lá e recompile.

Existem algumas coisas em Java que simplesmente não podem ser serializadas porque são específicas de tempo de execução. Coisas como streams, threads, tempo de execução, etc. e até mesmo algumas classs GUI (que estão conectadas ao SO subjacente) não podem ser serializadas.

Embora eu concorde com os pontos apresentados em outras respostas aqui, o verdadeiro problema é com a desserialização: se a definição de class muda, então há um risco real de que a desserialização não funcione. Nunca modificar os campos existentes é um grande compromisso para o autor de uma biblioteca! Manter a compatibilidade da API é o suficiente de uma tarefa como ela é.

Uma class que precisa ser persistida em um arquivo ou outra mídia deve implementar a interface Serializable, para que a JVM possa permitir que o object de class seja serializado. Por que a class Object não é serializada, então nenhuma das classs precisa implementar a interface, afinal, a JVM serializa a class apenas quando eu uso ObjectOutputStream, o que significa que o controle ainda está em minhas mãos para permitir que a JVM serialize.

A razão pela qual a class Object não é serializável por padrão no fato de que a versão da class é o principal problema. Portanto, cada class interessada na serialização deve ser marcada como Serializable explicitamente e fornecer um número de versão serialVersionUID.

Se serialVersionUID não for fornecido, obteremos resultados inesperados ao desserializar o object, por isso, a JVM lançará InvalidClassException se serialVersionUID não corresponder. Portanto, toda class tem que implementar a interface serializável e fornecer serialVersionUID para garantir que a class apresentada nas duas extremidades seja idêntica.