Pergunta

Quando implementos classe serializável em Eclipse, eu tenho duas opções: add serialVersionUID(1L) padrão ou serialVersionUID(3567653491060394677L) gerado. Acho que primeiro é mais frio, mas muitas vezes eu vi pessoas usando a segunda opção. Existe alguma razão para gerar long serialVersionUID?

Foi útil?

Solução

Tanto quanto eu posso dizer, isso seria apenas para compatibilidade com versões anteriores. Isso só seria útil se você esqueceu de usar um serialVersionUID antes, e, em seguida, fez uma mudança que você sabe deve ser compatível, mas que faz com que a serialização de quebrar.

Veja a Java serialização Spec para mais detalhes.

Outras dicas

O objetivo da versão de serialização UID é manter o controle de versões diferentes de uma classe, a fim de realizar a serialização válida de objetos.

A idéia é gerar um ID que é exclusivo para uma determinada versão de uma classe, que é então mudou quando houver novos detalhes adicionados à classe, como um novo campo, o que afetaria a estrutura do objeto serializado .

Sempre usando a mesma ID, tais como meios 1L que, no futuro, se a definição de classe é alterado que provoca alterações na estrutura do objeto serializado, haverá uma boa chance de que problemas ao tentar desserializar um objeto.

Se o ID for omitido, Java vai realmente calcular o ID para você com base em campos do objeto, mas eu acredito que é um processo caro, proporcionando assim um manualmente irá melhorar o desempenho.

Aqui está um par de links para artigos que discutem a serialização e controle de versão de classes:

A principal razão para o gerado seria para torná-lo compatível com uma versão existente da classe que já tem persistido cópias.

O padrão "longa" do serialVersionUID é o valor padrão conforme definido pelo Java serialização Especificação , calculado a partir do comportamento de serialização padrão.

Então, se você adicionar o número da versão padrão, sua classe (des) serialize mais rápido enquanto nada estruturalmente alterado, mas você vai ter que tomar cuidado para que, se você alterar a classe (campos adicionar / remover) você também atualizar o número de série.

Se você não tem que ser compatível com fluxos de bits existentes, você pode simplesmente colocar 1L lá e incrementar a versão conforme necessário, quando algo muda. Isto é, quando a versão de serialização padrão da classe alterado seria diferente da versão padrão da velha classe.

Você absolutamente deve criar um serialVersionUID cada vez que você definir Uma classe que implementa java.io.Serializable. Se você não fizer isso, uma vontade ser criado automaticamente para você, mas isso é ruim. A auto-gerada serialVersionUID é baseada nas assinaturas de método de sua classe, de modo se você mudar de classe no futuro, para adicionar um método (por exemplo), deserializing as versões "velhos" da classe irá falhar. Aqui está o que pode acontecer:

  1. Criar a primeira versão de sua classe, sem definir o serialVersionUID.
  2. Serialize uma instância de sua classe para um armazenamento persistente; uma serialVersionUID é gerado automaticamente para você.
  3. Modificar sua classe para adicionar um novo método, e reorientar a sua aplicação.
  4. Tentativa de desserializar a instância que foi publicado na etapa 2, mas agora ele falha (quando deveria ter sucesso), porque tem um diferente serialVersionUID gerado automaticamente.

Se você não especificar um serialVersionUID então Java faz uma na mosca. O serialVersionUID gerado é esse número. Se você mudar algo em sua classe que realmente não faz o seu incompatível classe com verisons serializados anteriores, mas muda o hash, então você precisa usar o gerado serialVersionUID muito-grande-número (ou o número "esperado" da mensagem de erro) . Caso contrário, se você está mantendo o controle de tudo mesmo, 0, 1, 2 ... é melhor.

Quando você usa serialVersionUID (1L) em vez de gerar serialVersionUID (3567653491060394677L) que você está dizendo algo.

Você está dizendo que você está 100% confiante de que nenhum sistema que nunca vai tocar essa classe que tenha uma versão serializada incompatível desta classe com um número de versão 1.

Se você pode pensar de qualquer desculpa para isso é história versão serializada ser desconhecido, que pode ser difícil de dizer com confiança. Em sua vida, uma classe bem sucedida será mantida por muitas pessoas, vivem em muitos projetos, e residir em muitos sistemas.

Você pode agonizar sobre isso. Ou você pode jogar na loteria esperando a perder. Se você gerar a versão que você tem uma pequena chance de coisas erradas acontecendo. Se você assumir "Hey eu aposto que ninguém usado 1 ainda" suas chances são maiores do que minúsculo. É precisamente porque todos nós pensamos 0 e 1 são legais que você tem maiores chances de bater-los.

-

Quando você gera serialVersionUID (3567653491060394677L) ao invés de uso serialVersionUID (1L) que você está dizendo algo.

Você está dizendo que as pessoas podem ter outros números de versão criado ou gerados manualmente sobre a história desta classe e você não se importa, porque Longs estão pirando grandes números.

De qualquer maneira, a menos que você sabe perfeitamente a história de números de versão usado quando a serialização a classe em todo o universo de onde se tem ou venha a existir, você está tendo uma chance. Se você tem o tempo para fazer 100% de certeza 1 é AOK, ir para ele. Se isso é de muito trabalho, vá em frente e cegamente gerar o número. Você é mais provável para ganhar na loteria do que ter aquela errado movimento. Se isso acontecer, deixe-me saber e eu vou te comprar uma cerveja.

Com toda essa conversa de jogar na loteria eu possa ter lhe dado a impressão de que serialVersionUID é gerada aleatoriamente. Na verdade, desde que o intervalo de números é distribuída uniformemente sobre cada valor possível de uma longa que seria ótimo. No entanto, é realmente feito desta forma:

http://docs.oracle. com / JavaSE / 6 / docs / plataforma / serialização / spec / class.html # 4100

A única diferença que você começa com isso é que você não precisa de uma fonte de forma aleatória. Você está usando as mudanças na própria classe para mudar o resultado. Mas de acordo com o princípio da casa dos pombos ainda há uma chance que poderia dar errado e ter uma colisão. É apenas incrivelmente improvável. Então, boa sorte para conseguir uma cerveja fora de mim.

No entanto, mesmo se a classe só vai viver em um sistema e uma base de código, pensando que incrementar o número à mão dá-lhe nenhuma chance de colisões significa apenas que você não entender os seres humanos. :)

Bem, serialVersionUID é uma exceção à regra de que “campos estáticos não se serializado”. ObjectOutputStream escreve cada vez que o valor de serialVersionUID no fluxo de saída. ObjectInputStream lê-lo de volta e se o valor lido a partir do fluxo não concordar com o valor serialVersionUID na versão atual da classe, em seguida, ele lança o InvalidClassException. Além disso, se não houver serialVersionUID oficialmente declarada na classe para ser serializado, compilador adiciona automaticamente com um valor gerado com base nos campos declarado na classe.

Porque em muitos casos id padrão não é única. por isso criamos id para fazer conceito único.

Para adicionar a resposta @ David Schmitts, como uma regra de ouro que eu sempre usar o 1L padrão fora da convenção. Eu só tinha de voltar e mudar alguns deles algumas vezes, mas eu sabia que quando eu fiz a mudança e atualizou o número padrão por um de cada vez.

Na minha empresa atual que exigem o número gerado automaticamente então eu uso isso para convenções, mas eu prefiro o padrão. Minha opinião é que, se não é uma convenção onde você trabalha, usar o padrão, a menos que você acha que vai ser constantemente mudando a estrutura de vocês serializado aulas por algum motivo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top