Question

Lorsque classe implémente Serializable dans Eclipse, j'ai deux options: ajouter défaut serialVersionUID(1L) ou généré serialVersionUID(3567653491060394677L). Je pense que le premier est un refroidisseur, mais plusieurs fois je voyais des gens en utilisant la deuxième option. Y at-il raison de générer long serialVersionUID?

Était-ce utile?

La solution

Pour autant que je peux dire, ce serait uniquement pour la compatibilité avec les versions précédentes. Ce ne serait utile que si vous avez omis d'utiliser un serialVersionUID avant, puis fait un changement que vous connaissez devrait être compatible, mais qui provoque la sérialisation briser.

Voir la Java sérialisation Spec plus de détails.

Autres conseils

Le but de l'UID version sérialisation est de garder une trace des différentes versions d'une classe afin d'effectuer sérialisation d'objets valides.

L'idée est de générer un identifiant unique à une certaine version d'une classe, qui est ensuite changé quand il y a de nouveaux détails ajoutés à la classe, comme un nouveau champ, ce qui aurait une incidence sur la structure de l'objet sérialisé .

Toujours en utilisant la même ID, tels que 1L signifie que, dans l'avenir, si la définition de la classe est changée, ce qui provoque des changements à la structure de l'objet sérialisé, il y aura une bonne chance que les problèmes en essayant de désérialiser un objet.

Si l'ID est omis, Java calculer effectivement l'ID pour vous en fonction des champs de l'objet, mais je crois qu'il est un processus coûteux, fournissant ainsi on manuellement améliorer les performances.

Voici ce sont quelques liens vers des articles qui traitent de sérialisation et versioning des classes:

La raison principale généré un serait de le rendre compatible avec une version existante de la classe qui a déjà persisté copies.

La valeur par défaut « long » de l'serialVersionUID est la valeur par défaut définie par le sérialisation Java Specification , calculé à partir du comportement de sérialisation par défaut.

Donc, si vous ajoutez le numéro de version par défaut, votre classe (dé) sérialisation plus rapide aussi longtemps que rien n'a structurellement changé, mais vous devez prendre soin que si vous changez la classe (ajouter / supprimer des champs) vous également mettre à jour le numéro de série.

Si vous ne devez pas être compatible avec les flux de bits existants, vous pouvez simplement mettre 1L là et incrémenter la version au besoin quand quelque chose change. Autrement dit, lorsque la version de sérialisation par défaut de la classe modifiée serait différente de la version par défaut de l'ancienne classe.

Vous devez absolument créer un serialVersionUID chaque fois que vous définissez une classe qui implémente java.io.Serializable. Si vous ne le faites pas, on être automatiquement créé pour vous, mais cela est mauvais. L'auto-généré serialVersionUID est basé sur les signatures de méthode de votre classe, donc si vous changez votre classe à l'avenir d'ajouter une méthode (par exemple), désérialisation les versions « anciens » de la classe échouera. Voici ce que peut se produire:

  1. Créez la première version de votre classe, sans définir la serialVersionUID.
  2. Sérialisez une instance de votre classe à un magasin persistant; une serialVersionUID est généré automatiquement pour vous.
  3. Modifier votre classe pour ajouter une nouvelle méthode, et de redéployer votre application.
  4. Tentative de désérialiser l'instance qui a été publié en feuilleton dans l'étape 2, mais maintenant il échoue (quand il doit réussir), car il a un différent serialVersionUID généré automatiquement.

Si vous ne spécifiez pas de serialVersionUID alors Java fait un à la volée. Le serialVersionUID généré correspond à ce nombre. Si vous changez quelque chose dans votre classe qui ne fait pas vraiment votre classe incompatible avec précédentes verisons sérialisés mais modifie le hachage, vous devez utiliser le produit très grand nombre serialVersionUID (ou le nombre « attendu » du message d'erreur) . Dans le cas contraire, si vous gardez une trace de tout vous-même, 0, 1, 2 ... est mieux.

Lorsque vous utilisez serialVersionUID (1L) plutôt que de générer serialVersionUID (3567653491060394677L) vous dites quelque chose.

Vous dites que vous êtes confiant à 100% qu'aucun système qui ne sera jamais toucher cette classe qui a une version sérialisée incompatible de cette classe avec un numéro de version 1.

Si vous pouvez penser à une excuse pour son histoire version sérialisée être inconnue, qui pourrait être difficile de dire avec confiance. Dans sa vie, sera maintenu une classe avec succès par de nombreuses personnes, vivent dans de nombreux projets, et résident dans de nombreux systèmes.

Vous pouvez agoniser sur cela. Vous pouvez aussi jouer à la loterie dans l'espoir de perdre. Si vous générez la version que vous avez une petite chance de choses vont mal. Si vous assumez « Hé, je parie que personne n'utilisé 1 encore » vos chances sont plus grandes que minuscules. C'est précisément parce que nous pensons que tous les 0 et 1 sont cool que vous avez des chances plus élevées de les frapper.

-

Lorsque vous générez serialVersionUID (3567653491060394677L) plutôt que d'utiliser serialVersionUID (1L) vous dites quelque chose.

Vous dites que les gens peuvent avoir soit manuellement créé ou généré d'autres numéros de version sur l'histoire de cette classe et vous ne vous inquiétez pas parce que désire ardemment sont paniquer grand nombre.

De toute façon, vous savez parfaitement à moins que l'histoire des numéros de version utilisée lors de la sérialisation de la classe dans l'univers entier où il a ou existera jamais, vous prenez une chance. Si vous avez le temps de faire 100% sûr 1 est AOK, allez-y. Si c'est à beaucoup de travail, aller de l'avant et de générer aveuglément le nombre. Vous avez plus de chances de gagner à la loterie que d'avoir qui vont mal. Le cas échéant, laissez-moi savoir et je vais vous acheter une bière.

Avec tout cela parle de jouer à la loterie je vous ai donné l'impression que serialVersionUID est généré au hasard. En fait, aussi longtemps que la gamme des nombres est répartie uniformément sur toutes les valeurs possibles d'une longue qui serait très bien. Cependant, il est effectivement fait de cette façon:

http://docs.oracle. com / JavaSE / 6 / docs / plate-forme / sérialisation / spec / class.html # 4100

La seule différence que vous obtenez avec qui vous n'avez pas besoin d'une source de hasard. Vous utilisez les changements de classe elle-même pour changer le résultat. Mais selon le principe de pigeonhole il y a encore une chance, il pourrait se tromper et d'avoir une collision. Il est juste incroyablement improbable. Alors bonne chance d'obtenir une bière hors de moi.

Cependant, même si la classe ne jamais vivre dans un système et une base de code, en pensant que incrémenter le numéro à la main vous donne aucune chance de collision signifie simplement que vous ne comprenez pas les humains. :)

Eh bien, serialVersionUID est une exception à la règle selon laquelle « les champs statiques ne reçoivent aucun numéro de série ». ObjectOutputStream écrit chaque fois que la valeur de serialVersionUID au flux de sortie. ObjectInputStream relit et si la valeur lue à partir du flux ne sont pas d'accord avec la valeur serialVersionUID dans la version actuelle de la classe, il jette le InvalidClassException. De plus, s'il n'y a pas serialVersionUID officiellement déclaré dans la classe à sérialiser, compilateur, il ajoute automatiquement avec une valeur générée en fonction des champs déclarés dans la classe.

Parce que dans de nombreux cas id par défaut est pas unique. Nous créons donc id pour faire concept unique.

Pour ajouter à la réponse Schmitts @ David, en règle générale, je toujours utiliser la valeur par défaut 1 L de convention. Je n'ai dû revenir en arrière et changer certains d'entre eux quelques fois, mais je savais que quand je fait le changement et mis à jour le numéro par défaut par un à chaque fois.

Lors de mon entreprise actuelle, ils exigent que le numéro généré automatiquement, donc j'utiliser pour la convention, mais je préfère la valeur par défaut. Mon point de vue est, si ce n'est pas une convention où vous travaillez, utilisez la valeur par défaut, à moins que vous pensez que vous serez en constante évolution de la structure des classes vous un numéro de série pour une raison quelconque.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top