226 votes

Pourquoi générer un serialVersionUID long au lieu d'un simple 1L ?

Lorsque la classe implémente Serializable dans Eclipse, j'ai deux options : ajouter la valeur par défaut de la classe. serialVersionUID(1L) ou généré serialVersionUID(3567653491060394677L) . Je pense que la première option est plus cool, mais j'ai souvent vu des gens utiliser la deuxième option. Y a-t-il une raison de générer long serialVersionUID ?

51 votes

En quoi est-ce une copie exacte ? Je ne demande pas pourquoi le générer du tout, mais pourquoi générer un long serialVersionUID.

13 votes

Quand Jon Skeet utilise serialVersionUID, il utilise 0L : stackoverflow.com/questions/605828/ ;)

9 votes

@HannoFietz : La phrase exacte est : "Pour simplifier, je suggère démarrage avec 0 et en l'augmentant de 1 chaque fois que vous en avez besoin." Donc, il semble qu'il utilise 0L seulement au début.

95voto

Michael Myers Points 82361

Pour autant que je sache, ce serait uniquement pour la compatibilité avec les versions précédentes. Cela ne serait utile que si vous avez négligé d'utiliser un serialVersionUID auparavant, et que vous avez ensuite effectué une modification dont vous savez qu'elle devrait être compatible mais qui entraîne une rupture de la sérialisation.

Voir le Spécification de sérialisation Java pour plus de détails.

78voto

coobird Points 70356

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

L'idée est de générer un identifiant unique pour une certaine version d'une classe, qui est ensuite modifié lorsque de nouveaux détails sont ajoutés à la classe, comme un nouveau champ, qui affecterait la structure de l'objet sérialisé.

Toujours utiliser le même identifiant, par exemple 1L signifie qu'à l'avenir, si la définition de la classe est modifiée, ce qui entraîne des changements dans la structure de l'objet sérialisé, il y a de fortes chances que des problèmes surviennent lors de la tentative de désérialisation d'un objet.

Si l'identifiant est omis, Java le calculera pour vous en se basant sur les champs de l'objet, mais je pense que c'est un processus coûteux, donc en fournir un manuellement améliorera les performances.

Voici quelques liens vers des articles qui traitent de la sérialisation et de la gestion des versions des classes :

55 votes

L'idée derrière l'utilisation de 1L est que vous l'incrémentez chaque fois que vous modifiez les propriétés ou les méthodes de la classe.

39 votes

Le fait de permettre la génération automatique du serialversionUID n'a aucun impact sur les performances d'exécution - il est généré à la compilation par javac... si vous décompilez le bytecode de la classe, vous verrez la variable de manière statique dans le bytecode.

11 votes

Une remarque supplémentaire : en gérant le nombre explicitement, vous pouvez décider quand vous considérez les versions d'une classe comme "compatibles", plutôt que d'exiger que la définition de la classe soit exactement la même.

22voto

Robin Points 15032

La raison principale de la création de la classe est de la rendre compatible avec une version existante de la classe qui possède déjà des copies persistantes.

2 votes

OK mais ce sera la même chose si j'ai toujours 1L. Tout sera compatible même si je fais un changement.

0 votes

@grep essayez de renommer un champ et voyez ce qui se passe.

1 votes

@grep le point est que si vous avez une classe qui a omis le serialVersionUID avant, il aurait obtenu celui généré automatiquement. Donc maintenant, vous voulez commencer à le définir explicitement, le définir à 1L le rendrait incompatible avec la classe existante, alors qu'utiliser la valeur générée le garde compatible.

15voto

David Schmitt Points 29384

Le défaut "long" de la serialVersionUID est la valeur par défaut telle que définie par le Spécification de sérialisation Java calculé à partir du comportement de sérialisation par défaut.

Ainsi, si vous ajoutez le numéro de version par défaut, votre classe se (dé)sérialise plus rapidement tant que rien n'a été modifié sur le plan structurel, mais vous devrez veiller à ce que, si vous modifiez la classe (ajout/suppression de champs), vous mettiez également à jour le numéro de série.

Si vous n'avez pas besoin d'être compatible avec les flux binaires existants, vous pouvez simplement mettre 1L et incrémenter la version si nécessaire lorsque quelque chose change. C'est-à-dire, 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.

7voto

joeforker Points 14483

Si vous ne spécifiez pas de serialVersionUID, Java en crée un à la volée. Le serialVersionUID généré est ce numéro. Si vous modifiez quelque chose dans votre classe qui ne la rend pas vraiment incompatible avec les versions sérialisées précédentes mais qui modifie le hachage, vous devez utiliser le serialVersionUID généré avec un très grand nombre (ou le nombre "attendu" du message d'erreur). Sinon, si vous gardez une trace de tout vous-même, 0, 1, 2... est préférable.

0 votes

Vous voulez dire ==> 1. Si vous voulez que différentes modifications de classes soient compatibles, utilisez celle qui est générée. 2. Si vous voulez que différentes versions de classes soient incompatibles, utilisez celle par défaut, et soyez prudent dans l'incrémentation. Ai-je bien compris ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X