serialVersionUID
facilite la gestion des versions des données sérialisées. Sa valeur est stockée avec les données lors de la sérialisation. Lors de la dé-sérialisation, la même version est vérifiée pour voir comment les données sérialisées correspondent au code actuel.
Si vous voulez faire une version de vos données, vous commencez normalement par un fichier serialVersionUID
de 0, et la modifier à chaque changement structurel de votre classe qui modifie les données sérialisées (ajout ou suppression de champs non transitoires).
Le mécanisme de désérialisation intégré ( in.defaultReadObject()
) refusera de désérialiser les anciennes versions des données. Mais si vous le souhaitez, vous pouvez définir votre propre méthode de désérialisation. readObject() -Cette fonction permet de relire les anciennes données. Ce code personnalisé peut alors vérifier le serialVersionUID
afin de savoir dans quelle version se trouvent les données et de décider comment les désérialiser. Cette technique de versionnage est utile si vous stockez des données sérialisées qui survivent à plusieurs versions de votre code.
Mais le stockage de données sérialisées pendant une période aussi longue n'est pas très courant. Il est beaucoup plus courant d'utiliser le mécanisme de sérialisation pour écrire temporairement des données dans un cache, par exemple, ou pour les envoyer par le réseau à un autre programme possédant la même version des parties concernées du code de base.
Dans ce cas, vous n'êtes pas intéressé par le maintien de la compatibilité ascendante. Vous voulez seulement vous assurer que les bases de code qui communiquent ont bien les mêmes versions des classes concernées. Afin de faciliter une telle vérification, vous devez maintenir la classe serialVersionUID
comme avant et n'oubliez pas de le mettre à jour lorsque vous apportez des modifications à vos classes.
Si vous oubliez de mettre à jour le champ, vous risquez de vous retrouver avec deux versions différentes d'une classe, avec une structure différente mais avec la même serialVersionUID
. Si cela se produit, le mécanisme par défaut ( in.defaultReadObject()
) ne détectera aucune différence, et essaiera de désérialiser les données incompatibles. Vous risquez alors de vous retrouver avec une erreur d'exécution cryptique ou un échec silencieux (champs nuls). Ces types d'erreurs peuvent être difficiles à trouver.
Ainsi, pour faciliter ce cas d'utilisation, la plate-forme Java vous offre la possibilité de ne pas définir l'option serialVersionUID
manuellement. Au lieu de cela, un hachage de la structure de la classe sera généré à la compilation et utilisé comme identifiant. Ce mécanisme permet de s'assurer que vous n'avez jamais de structures de classe différentes avec le même identifiant, et donc que vous n'aurez pas ces échecs de sérialisation à l'exécution difficiles à tracer mentionnés ci-dessus.
Mais il y a un revers à la stratégie de l'identifiant généré automatiquement. En effet, les identifiants générés pour une même classe peuvent différer d'un compilateur à l'autre (comme l'a mentionné Jon Skeet ci-dessus). Donc, si vous communiquez des données sérialisées entre du code compilé avec différents compilateurs, il est recommandé de maintenir les ids manuellement de toute façon.
Et si vous êtes rétrocompatible avec vos données, comme dans le premier cas d'utilisation mentionné, vous souhaitez probablement aussi maintenir l'identifiant vous-même. Ceci afin d'obtenir des identifiants lisibles et d'avoir un meilleur contrôle sur le moment et la manière dont ils sont modifiés.
4 votes
Trouvez une bonne pratique concernant serialversionUID ; dzone.com/articles/what-is-serialversionuid