Que signifie 1L serialVersionUID? Quand pourrais-je utiliser cette valeur par défaut 1L?

Il existe 3 façons de définir le serialVersionUID:

1. private static final long serialVersionUID = 1L; (Default) 2. private static final long serialVersionUID = -8940196742313994740L; (Generated) 3. Don't define serialVersionUID and let the JVM define it at runtime. @Lance Java 

Mais je ne comprends pas la première façon!

Je l’ai déjà vu, quelqu’un définit “serialVersionUID = 1L” pour toutes les classes Java dans le code source.

Quel est le sens? Est-ce utile?

Si toutes les classes ont le même serialVersionUID 1L, n’y a-t-il pas de problème?

Quel est le sens? Est-ce utile?

Oui. Le but de serialVersionUID est de donner au programmeur le contrôle sur les versions d’une classe considérées comme incompatibles en ce qui concerne la sérialisation. Tant que le serialVersionUID rest le même, le mécanisme de sérialisation fera de son mieux pour traduire les instances sérialisées, ce qui peut ne pas être ce que vous voulez. Si vous effectuez un changement sémantique qui rend les anciennes versions incompatibles, vous pouvez modifier le serialVersionUID pour que la désérialisation des anciennes instances échoue.

Si toutes les classes ont le même serialVersionUID 1L, n’y a-t-il aucun problème?

Non – le serialVersionUID est par classe .

Ceci est expliqué ici :

SerialVersionUID est un identificateur de version universel pour une classe Serializable. La désérialisation utilise ce nombre pour s’assurer qu’une classe chargée correspond exactement à un object sérialisé. Si aucune correspondance n’est trouvée, une exception InvalidClassException est lancée.


Du javadoc :

L’exécution de la sérialisation associe à chaque classe sérialisable un numéro de version, appelé serialVersionUID, utilisé lors de la désérialisation pour vérifier que l’expéditeur et le destinataire d’un object sérialisé ont chargé pour cet object des classes compatibles avec la sérialisation. Si le destinataire a chargé une classe pour l’object dont l’ID de série est différent de celui de la classe de l’expéditeur correspondante, la désérialisation entraîne une exception InvalidClassException. Une classe sérialisable peut déclarer explicitement son propre serialVersionUID en déclarant un champ nommé “serialVersionUID” qui doit être statique, final et de type long:


Liens utiles

  1. java.io.Serializable
  2. Pourquoi devrais-je me soucier de serialVersionUID? (StackOverflow)
  3. serialVersionUID dans la sérialisation Java

La JVM InvalidClassException une InvalidClassException si l’ serialVersionUID d’un object sérialisé sérialisé ne correspond pas à l’ serialVersionUID de la classe sous laquelle elle est désérialisée.

Le serialVersionUID d’une classe doit changer chaque fois que la classe change de manière incompatible. Normalement, cela signifie que chaque fois que vous modifiez la shape d’une classe (par exemple, les champs ou les méthodes changent).

Il y a des cas où vous ne voulez pas que serialVersionUID change. Par exemple, vous pouvez accepter les anciennes versions de l’object dans votre application. Dans ce cas, vous pouvez laisser le serialVersionUID identique et les nouveaux champs seront considérés comme nuls.

Oui, j’ai vu du code qui définissait serialVersionUID comme ça aussi. Je pense que c’est une mauvaise idée.

Dans ce contexte, il n’y a qu’une seule valeur “distinguée” pour le champ serialVersionUID ; soit zéro … 0L . Zéro signifie “calculer l’ID de version lors de l’exécution en appliquant l’algorithme standard” en fonction de la classe réelle que vous sérialisez / désérialisez. Cela signifie que chaque fois que la signature de sérialisation effective de votre code change, le code de sérialisation / désérialisation utilisera un identifiant de version différent. Du sharepoint vue de la sécurité (du sharepoint vue général), il s’agit de la chose la plus sûre à faire, même si elle est quelque peu inefficace et de manière plus fragile.

Quel est le sens?

Le 1L n’a pas de signification particulière. C’est juste un nombre qui correspondra à 1L comme “autre” identifiant de version.

À mon avis, il est préférable d’utiliser 0L ou un numéro de version (à un moment donné) généré à l’aide de l’algorithme standard.

  • Si vous utilisez 0L , vous obtenez des exceptions de désérialisation définitives si les classes changent d’une manière qui pourrait être source de problèmes. Si vous en avez besoin , c’est une bonne chose.

  • D’autre part, vous utilisez un identifiant de version généré, vous (le programmeur) pouvez décider vous-même de la date de régénération de l’identifiant. Et lorsque vous décidez de régénérer, l’identifiant ne changera que si la signature de la classe a changé. (Si la représentation des classes, etc. n’a pas changé, la signature régénérée doit être identique à celle d’origine!) Et lorsque l’identifiant change, vous pouvez envisager d’append des méthodes personnalisées (‘readObject’, etc.) pour traiter l’incompatibilité. .

  • Cependant, si vous utilisez 1L , vous ne pouvez pas savoir si l’ID de version doit changer sans vérifier l’historique de votre code et comparer les versions anciennes / nouvelles des classes … aussi loin que vous le souhaitez.

Est-ce utile?

Cela dépend de ce que vous considérez comme “utile”. Si vous pensez que c’est une bonne chose de twigr l’identifiant de la version à “croyez-moi, c’est ok”, alors 1L est utile.


serialVersionUID souviens bien, certaines versions d’Eclipse offrent 1L comme l’une des corrections automatiques possibles pour un avertissement de champ serialVersionUID manquant. C’est probable d’où viennent les cas que vous voyez.

Imaginez que vous écrivez une classe avec un serialVersionUID , instanciez-le, puis sérialisez-le dans un fichier (avec ObjectOutputStream)

Ensuite, vous modifiez la classe.

Ensuite, avec la classe modifiée, vous désérialisez (lisez) la version que vous avez sérialisée avant la modification. Java vérifiera le serialVersionUID de la classe actuelle et de la classe sérialisée, et si elles ne correspondent pas, la désérialisation échouera. Ceci est délibérément un échec pour éviter que des erreurs beaucoup plus subtiles (et plus difficiles à déboguer) se produisent plus tard en raison d’incompatibilités de version de classe.

Si vous omettez serialVersionUID vous désactivez la vérification de la version. Si vous définissez toujours si sur 1L, la vérification sera toujours réussie (la valeur est toujours la même), de sorte que vous êtes toujours vulnérable aux problèmes d’incompatibilité de version de classe subtile.

La valeur est utilisée lors de la sérialisation d’un object et de la désérialisation de l’object dans JVM.

En outre, si votre classe change et que vous ne souhaitez pas prendre en charge la compatibilité ascendante (c’est-à-dire capable de désérialiser l’object renvoyé qui a été sérialisé à l’aide de votre dernière version de classe), vous pouvez modifier le numéro de version en une autre valeur.

Cependant, pour prendre en charge la compatibilité ascendante, vous devez conserver le même numéro de version que la valeur précédemment définie pour serialVersionUID.

La meilleure pratique consiste à modifier le serialVersionUID chaque fois que des modifications incompatibles sont apscopes à la classe.

Vous pouvez affecter n’importe quelle valeur long à serialVersionUID , mais vous devez la changer chaque fois que vous modifiez votre classe.

La seconde ressemble à un serialVersionUID généré, basé sur les fonctionnalités de la version actuelle de la classe.

Il est important de préciser que l’implémentation d’une classe dans l’interface Serializable fait que TOUS les champs non déclarés soient des éléments transient de l’ API exscope de la classe, que ces champs soient déclarés private ou non.

En d’autres termes, implémenter Serializable:

  • casse l’encapsulation. Si la classe a une chance de devenir une classe réussie et de longue durée, vous devez prendre en charge le formulaire sérialisé … pour toujours.

  • peut sérieusement compromettre votre capacité à faire évoluer cette classe, précisément parce qu’elle fait partie de son API exscope. L’alternative est de briser la compatibilité en amont.

  • peut créer des problèmes de sécurité pour votre classe et son application. La désérialisation représente un moyen de créer des objects Java sans constructeur. Il est donc possible de violer les invariants d’une classe en fournissant des stream d’octets non autorisés à l’installation de désérialisation.

Le serialVerionUID doit être considéré comme une propriété du formulaire sérialisé . Il est destiné à indiquer à une machine virtuelle Java s’il existe ou non une différence entre la forme sérialisée d’une instance de classe qu’elle reçoit et la forme sérialisée de la même classe rendue (éventuellement) ailleurs.

Vous pouvez voir les problèmes potentiels qui peuvent survenir si les formulaires sérialisés sont différents mais que les UID sont identiques. La JVM récepsortingce supposera que la version du formulaire série reçue entre une ancienne classe et la nouvelle est la même si elles ne le sont pas et poursuivront consciencieusement en essayant de désérialiser le stream d’octets.

TLDR: Vous ne devriez pas changer l’UID quand vous en avez envie. Vous devez le changer lorsque la forme sérialisée de la classe change afin que les versions de logiciels qui utilisent des versions plus anciennes de votre classe (avec la forme sérialisée différente) soient interrompues au lieu de faire (éventuellement en silence) la mauvaise chose. Ne pas concevoir un bon formulaire sérialisé pour vos classes rendra plus difficile (encore plus difficile) la rétrocompatibilité pour ses clients. Dans le cas idéal, la forme sérialisée pour une classe persiste tout au long de son évolution (et donc son UID ne change jamais).