Question

Pourquoi pas le serialVersionUID généré automatiquement? Je courais dans un problème sur un serveur d'applications où apparemment une ancienne classe était mise en mémoire cache.

Était-ce utile?

La solution

serialVersionUID n'est pas généré automatiquement parce qu'il est dangereux. Lorsque serialVersionUID est défini, il implique que deux versions d'une classe sont compatibles avec le respect de la sérialisation.

Imaginez que vous avez une classe appelée Foo, et il a pas serialVersionUID (par défaut), et vous sérialiser une instance de Foo dans un fichier. Par la suite, vous ajoutez de nouveaux membres à la classe Foo. Si vous essayez de désérialiser l'objet Foo à partir du fichier, vous obtiendrez un échec de sérialisation indiquant que les objets sont incompatibles. Ils sont incompatibles, c'est ce que vous voulez et est la valeur par défaut. Ils sont incompatibles parce que les nouveaux membres de la classe Foo ne peuvent être réinitialisés de l'ancienne instance sérialisée de Foo.

Maintenant, vous pourriez dire: « Je ne me soucie pas, dans ma demande il est acceptable pour les champs à UNINITIALIZED ». Si ce vraiment est le cas, vous pouvez régler le serialVersionUID du nouveau class Foo être le même que le vieux classe Foo. Cela dit Java que les objets sont compatibles avec le respect de serializablity et Java ne se plaindra pas lorsque vous désérialiser l'ancienne instance de Foo dans la nouvelle classe Foo (mais les nouveaux champs seront encore être UNINITIALIZED).

Si vous créez une nouvelle classe pour la première fois, et vous définissez le serialVersionUID, vous entrez un contrat . Ce contrat est, « Pour toutes les versions futures de cette classe avec le même serialVersionUID, je vous garantis qu'ils sont compatibles avec le respect de l'état et sérialisation » .

Si vous changez une classe, et vous explicitement voulez disallow désérialisation des anciennes versions, vous pouvez changer la serialVersionUID à une nouvelle valeur. Cela entraînera une exception à levée si un objet ancien est tenté d'être désérialisé dans une nouvelle instance de classe.

Autres conseils

Il est généré automatiquement, en fonction de la structure de la classe. Si la structure change, l'identifiant est régénéré (selon le sérialisation spécification il est hashof la classe).

Alors vous feriez mieux de définir une serialVersionUID explicite.

Si vous utilisez Eclipse comme IDE, vous pouvez cliquer droit sur l'avertissement au sujet de la serialVersionUID manquant et vous aurez deux options:

1) Définir la valeur par défaut Eclipse, qui a la valeur 1L; ou
2) Définition d'une valeur de temps générée de manière aléatoire

Si vous vous souciez de versioning des objets sérialisés, vous devrez régénérer manuellement une nouvelle valeur chaque fois que vous modifiez la classe. Le Javadoc pour l'interface Serializable a ceci à dire au sujet de ce qui se passe si vous ne déclarez pas du tout serialVersionUID:

  

Si une classe sérialisable ne déclare pas explicitement serialVersionUID, l'environnement d'exécution de sérialisation calcule une valeur de serialVersionUID par défaut pour cette classe en fonction de divers aspects de la classe, comme décrit dans l'objet sérialisation spécification Java (TM). Cependant, il est fortement recommandé que toutes les classes sérialisables déclarent explicitement les valeurs serialVersionUID, étant donné que le calcul de serialVersionUID par défaut est très sensible aux détails de classe qui peuvent varier en fonction des implémentations compilateur, et peuvent ainsi entraîner des InvalidClassExceptions inattendus lors de la désérialisation. Par conséquent, pour garantir une valeur serialVersionUID cohérente entre les différentes implémentations du compilateur Java, une classe sérialisable doit déclarer une valeur de serialVersionUID explicite.

Dans la pratique, j'ai trouvé que même si vous commencez avec le code source identique sur deux ou plusieurs machines (vérifié de Subversion, par exemple) où serialVersionUID a été non défini dans une classe, la valeur générée par le compilateur dans la classe est différent sur chaque machine lorsque le code est compilé. Cela peut provoquer des erreurs de confusion au cours du développement.

Si vous êtes sûr que vous ne serez jamais une situation où vous avez des objets sérialisés obsolètes qui sont hors de synchronisation avec une version plus récente de la classe (ou deux JVMs envoie sérialisé hors synchronisation des objets les uns aux autres , peut-être à travers un réseau ou une connexion socket), puis il suffit de définir une valeur de 1 litre pour serialVersionUID et laisser cette façon pour toujours.

http: // download-LLNW .oracle.com / JavaSE / 6 / docs / api / java / io / Serializable.html

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