Pourquoi le serialVersionUID n’est-il pas généré automatiquement?

Pourquoi le serialVersionUID n’est-il pas serialVersionUID automatiquement? Je rencontrais un problème sur un serveur d’applications où, apparemment, une ancienne classe était mise en cache.

serialversionuid n’est pas généré automatiquement car il est dangereux. Lorsque serialversionuid est défini, cela implique que deux versions d’une classe sont compatibles en ce qui concerne la sérialisation.

Imaginez que vous ayez une classe appelée Foo, qui n’a pas serialversionuid (valeur par défaut), et que vous sérialisiez une instance de Foo dans un fichier. Plus tard, vous ajoutez de nouveaux membres à la classe Foo. Si vous essayez de désérialiser l’object Foo du fichier, vous obtiendrez un échec de la sérialisation indiquant que les objects sont incompatibles. Ils sont incompatibles, c’est ce que vous voulez et c’est la valeur par défaut. Ils sont incompatibles car les nouveaux membres de la classe Foo ne peuvent pas être initialisés à partir de l’ancienne instance sérialisée de Foo.

Maintenant, vous pourriez dire: “Je m’en fiche, dans mon application, il est acceptable que ces champs soient non initialisés”. Si tel est vraiment le cas, vous pouvez définir la valeur serialversionuid de la nouvelle classe Foo identique à celle de l’ ancienne classe Foo. Cela indiquera à Java que les objects sont compatibles en ce qui concerne la sérialisation, et Java ne se plaindra pas lorsque vous désérialiserez l’ancienne instance de Foo dans la nouvelle classe Foo (mais les nouveaux champs ne seront toujours pas initialisés).

Si vous créez une nouvelle classe pour la première fois et que vous définissez serialversionuid, vous entrez un contrat . Ce contrat est le suivant: “Pour toutes les versions futures de cette classe avec la même version série, je garantirai leur compatibilité avec l’état et la sérialisation” .

Si vous modifiez une classe et que vous souhaitez explicitement interdire la désérialisation d’anciennes versions, vous pouvez remplacer serialversionuid par une nouvelle valeur. Cela provoquera la levée d’une exception si un ancien object est essayé pour être désérialisé dans une nouvelle instance de classe.

Il est généré automatiquement en fonction de la structure de la classe. Si la structure change, l’id est régénéré (conformément à la spécification de sérialisation, il s’agit de la classe hashof).

Donc, vous feriez mieux de définir un serialVersionUID explicite.

Si vous utilisez Eclipse en tant qu’EDI, vous pouvez cliquer avec le bouton droit de la souris sur l’avertissement concernant le numéro de série manquant et vous aurez deux options:

1) Définissez la valeur par défaut d’Eclipse, qui a la valeur 1L; ou
2) Définir une valeur longue générée aléatoirement

Si vous vous souciez de la gestion des versions des objects sérialisés, vous devrez régénérer manuellement une nouvelle valeur chaque fois que vous modifiez la classe. La Javadoc de l’interface Serializable a ceci à dire sur ce qui se passe si vous ne déclarez pas du tout serialVersionUID:

Si une classe sérialisable ne déclare pas explicitement un serialVersionUID, le moteur d’exécution de la sérialisation calculera une valeur serialVersionUID par défaut pour cette classe en fonction de divers aspects de la classe, comme décrit dans la spécification de sérialisation d’object Java (TM). Cependant, il est vivement recommandé que toutes les classes sérialisables déclarent explicitement les valeurs serialVersionUID, car le calcul par défaut serialVersionUID est très sensible aux détails de classe qui peuvent varier en fonction de l’implémentation du compilateur et peuvent donc entraîner des exceptions InvalidClassException inattendues lors de la désérialisation. Par conséquent, pour garantir une valeur serialVersionUID cohérente dans différentes implémentations du compilateur Java, une classe sérialisable doit déclarer une valeur serialVersionUID explicite.

En pratique, j’ai constaté que même si vous démarrez avec un code source identique sur deux ou plusieurs machines (extraites de Subversion, par exemple) où serialVersionUID n’était pas défini dans une classe, la valeur générée par le compilateur dans la classe était différente chaque fois. machine lorsque le code est compilé. Cela peut entraîner des erreurs de confusion lors du développement.

Si vous êtes sûr que vous ne rencontrerez jamais d’objects sérialisés périmés qui ne sont pas synchronisés avec une version plus récente de la classe (ou deux machines virtuelles qui envoient des objects sérialisés désynchronisés, peut-être de une connexion réseau ou socket) puis définissez simplement une valeur de 1L pour serialVersionUID et laissez-la ainsi pour toujours.

http://download-llnw.oracle.com/javase/6/docs/api/java/io/Serializable.html