Qu’est-ce qu’un serialVersionUID et pourquoi devrais-je l’utiliser?

Eclipse émet des avertissements lorsqu’un serialVersionUID est manquant.

La classe serializable Foo ne déclare pas un champ serialVersionUID final statique de type long

Qu’est-ce que serialVersionUID et pourquoi est-ce important? S’il vous plaît montrer un exemple où manquant serialVersionUID causera un problème.

    Les documents de java.io.Serializable sont probablement une explication aussi bonne que celle que vous obtiendrez:

    Le runtime de 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 des classes chargées pour cet object compatibles avec la sérialisation. Si le récepteur a chargé une classe pour l’object ayant un serialVersionUID différent de celui de la classe de l’expéditeur correspondant, la désérialisation entraînera une 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 :

     ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L; 

    Si une classe sérialisable ne déclare pas explicitement un serialVersionUID, le runtime de sérialisation calcule 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 fortement recommandé que toutes les classes sérialisables déclarent explicitement les valeurs serialVersionUID, car le calcul serialVersionUID par défaut est très sensible aux détails de classe qui peuvent varier en fonction des implémentations du compilateur et peuvent donc entraîner des InvalidClassExceptions inattendues. Par conséquent, pour garantir une valeur serialVersionUID cohérente sur les différentes implémentations du compilateur Java, une classe sérialisable doit déclarer une valeur serialVersionUID explicite. Il est également fortement recommandé que les déclarations serialVersionUID explicites utilisent le modificateur private lorsque cela est possible, car ces déclarations ne s’appliquent qu’à la classe déclarant immédiatement – les champs serialVersionUID ne sont pas utiles en tant que membres hérités.

    Si vous sérialisez simplement parce que vous devez sérialiser pour l’implémentation (qui se soucie si vous sérialisez pour une session HTTPS, par exemple … si elle est stockée ou non, vous ne vous souciez probablement pas de désérialiser un object de formulaire) , alors vous pouvez ignorer cela.

    Si vous utilisez la sérialisation, il est important que vous envisagiez de stocker et de récupérer directement des objects en utilisant la sérialisation. SerialVersionUID représente votre version de classe et vous devez l’incrémenter si la version actuelle de votre classe n’est pas compatible avec sa version précédente.

    La plupart du temps, vous n’utiliserez probablement pas directement la sérialisation. Si tel est le cas, générez un uid sérialisable par défaut en cliquant sur l’option de réparation rapide et ne vous inquiétez pas.

    Je ne peux pas laisser passer cette occasion pour twigr le livre de Josh Bloch, Effective Java (2nd Edition). Le chapitre 11 est une ressource indispensable sur la sérialisation Java.

    Selon Josh, l’UID généré automatiquement est généré en fonction d’un nom de classe, d’interfaces implémentées et de tous les membres publics et protégés. Changer l’un de ces éléments de quelque manière que ce soit changera le serialVersionUID . Vous n’avez donc pas besoin de vous en occuper uniquement si vous êtes certain que plus d’une version de la classe ne sera jamais sérialisée (que ce soit à travers des processus ou extraite du stockage ultérieurement).

    Si vous les ignorez pour le moment, et trouvez plus tard que vous devez changer la classe d’une certaine manière mais que vous maintenez la compatibilité avec l’ancienne version de la classe, vous pouvez utiliser l’outil serialVersionUID sur l’ ancienne classe et définir explicitement que sur la nouvelle classe. (En fonction de vos modifications, vous devrez peut-être également implémenter une sérialisation personnalisée en ajoutant des méthodes writeObject et readObject – voir javadoc Serializable ou chapitre 11 précité).

    Vous pouvez dire à Eclipse d’ignorer ces avertissements serialVersionUID:

    Fenêtre> Préférences> Java> Compilateur> Erreurs / Avertissements> Problèmes de programmation potentiels

    Au cas où vous ne le sauriez pas, il y a beaucoup d’autres avertissements que vous pouvez activer dans cette section (ou même des erreurs), beaucoup sont très utiles:

    • Problèmes potentiels de programmation: affectation booléenne accidentelle possible
    • Problèmes potentiels de programmation: access au pointeur nul
    • Code inutile: la variable locale n’est jamais lue
    • Code inutile: contrôle null redondant
    • Code inutile: diffusion inutile ou «instanceof»

    et beaucoup plus.

    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 souhaitez mettre à jour vos données, vous devez normalement commencer par un serialVersionUID 0 et le modifier à chaque modification structurelle de votre classe, ce qui modifie les données sérialisées (ajout ou suppression de champs non transitoires).

    Le mécanisme de in.defaultReadObject() ( in.defaultReadObject() ) refusera de in.defaultReadObject() anciennes versions des données. Mais si vous le souhaitez, vous pouvez définir votre propre fonction readObject () capable de lire les anciennes données. Ce code personnalisé peut alors vérifier le serialVersionUID pour savoir dans quelle version se serialVersionUID les données et décider comment le serialVersionUID . Cette technique de gestion des versions est utile si vous stockez des données sérialisées qui survivent à plusieurs versions de votre code.

    Mais stocker des données sérialisées sur 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 sur un cache, par exemple, ou l’envoyer sur le réseau vers un autre programme avec la même version des parties pertinentes du code.

    Dans ce cas, vous n’êtes pas intéressé par la compatibilité ascendante. Vous ne faites que vous assurer que les bases de code qui communiquent ont bien les mêmes versions des classes pertinentes. Pour faciliter une telle vérification, vous devez conserver le serialVersionUID comme avant et ne pas oublier de le mettre à jour lorsque vous serialVersionUID vos classes.

    Si vous oubliez de mettre à jour le champ, vous pourriez vous retrouver avec deux versions différentes d’une classe avec une structure différente mais avec le même serialVersionUID . Si cela se produit, le mécanisme par défaut ( in.defaultReadObject() ) ne détectera aucune différence et tentera de désérialiser les données incompatibles. Maintenant, vous pourriez vous retrouver avec une erreur d’exécution cryptique ou un échec silencieux (champs nuls). Ces types d’erreurs peuvent être difficiles à trouver.

    Donc, pour aider cette solution, la plate-forme Java vous offre le choix de ne pas définir le serialVersionUID manuellement. Au lieu de cela, un hachage de la structure de classe sera généré à la compilation et utilisé comme identifiant. Ce mécanisme garantira que vous n’avez jamais différentes structures de classes avec le même identifiant, et vous n’obtiendrez donc pas ces échecs de sérialisation d’exécution difficiles à suivre mentionnés ci-dessus.

    Mais il existe un backside à la stratégie d’identification générée automatiquement. À savoir que les identifiants générés pour la même classe peuvent différer entre les compilateurs (comme mentionné par 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 conserver les identifiants manuellement de toute façon.

    Et si vous êtes rétrocompatible avec vos données, comme dans le premier cas d’utilisation mentionné, vous souhaiterez probablement également conserver l’identifiant vous-même. Ceci afin d’obtenir des identifiants lisibles et de mieux contrôler quand et comment ils changent.

    Qu’est-ce qu’un serialVersionUID et pourquoi devrais-je l’utiliser?

    SerialVersionUID est un identifiant unique pour chaque classe, JVM utilise pour comparer les versions de la classe en s’assurant que la même classe a été utilisée lors de la sérialisation est chargée lors de la désérialisation.

    Le fait d’en spécifier un donne plus de contrôle, même si JVM en génère un si vous ne le spécifiez pas. La valeur générée peut différer entre différents compilateurs. De plus, il arrive que vous souhaitiez, pour une raison quelconque, interdire la désérialisation des anciens objects sérialisés [ backward incompatibility ], et dans ce cas, il vous suffit de changer le serialVersionUID.

    Les javadocs pour Serializable disent :

    Le calcul par défaut serialVersionUID est très sensible aux détails de classe qui peuvent varier en fonction des implémentations du compilateur et peuvent donc entraîner une InvalidClassException inattendue lors de la désérialisation.

    Par conséquent, vous devez déclarer serialVersionUID car cela nous donne plus de contrôle .

    Cet article a quelques bons points sur le sujet.

    La question originale a demandé “pourquoi est-ce important” et “exemple” où cet Serial Version ID serait utile. Eh bien j’en ai trouvé un.

    Disons que vous créez une classe Car , instanciez-la et écrivez-la dans un stream d’objects. L’object de voiture aplati se trouve dans le système de fichiers pendant un certain temps. En attendant, si la classe Car est modifiée en ajoutant un nouveau champ. Plus tard, lorsque vous essayez de lire (désérialiser) l’object Car aplati, vous obtenez l’ java.io.InvalidClassException , car un identifiant unique est automatiquement atsortingbué à toutes les classes sérialisables. Cette exception est levée lorsque l’identifiant de la classe n’est pas égal à l’identifiant de l’object aplati. Si vous y pensez vraiment, l’exception est lancée en raison de l’ajout du nouveau champ. Vous pouvez éviter que cette exception ne soit levée en contrôlant vous-même la version en déclarant un identifiant serialVersionUID explicite. La déclaration explicite de votre serialVersionUID (car il ne doit pas être calculé) présente également un petit avantage en serialVersionUID performances. Il est donc recommandé d’append votre propre serialVersionUID à vos classes Serializable dès que vous les créez, comme indiqué ci-dessous:

     public class Car { static final long serialVersionUID = 1L; //assign a long value } 

    Si vous obtenez cet avertissement sur une classe que vous ne pensez jamais à la sérialisation, et que vous ne vous êtes pas déclaré implements Serializable , c’est souvent parce que vous avez hérité d’une super-classe, qui implémente Serializable. Souvent, il serait préférable de déléguer à un tel object au lieu d’utiliser l’inheritance.

    Donc, au lieu de

     public class MyExample extends ArrayList { public MyExample() { super(); } ... } 

    faire

     public class MyExample { private List myList; public MyExample() { this.myList = new ArrayList(); } ... } 

    et dans les méthodes appropriées, appelez myList.foo() au lieu de this.foo() (ou super.foo() ). (Cela ne correspond pas à tous les cas, mais encore assez souvent.)

    Je vois souvent des gens prolonger JFrame ou autre, alors qu’ils n’ont besoin que de déléguer à cela. (Cela permet également de compléter automatiquement un IDE, car JFrame dispose de centaines de méthodes dont vous n’avez pas besoin lorsque vous souhaitez appeler vos personnalisations dans votre classe.)

    Un cas où l’avertissement (ou le serialVersionUID) est inévitable est lorsque vous étendez depuis AbstractAction, normalement dans une classe anonyme, en ajoutant uniquement la méthode actionPerformed. Je pense qu’il ne devrait pas y avoir d’avertissement dans ce cas (puisque vous ne pouvez normalement pas sérialiser et désérialiser de telles classes anonymes sur différentes versions de votre classe), mais je ne sais pas comment le compilateur pourrait le reconnaître.

    Si vous n’avez jamais besoin de sérialiser vos objects pour octroyer un tableau et les envoyer / stocker, vous n’avez pas à vous en préoccuper. Si vous le faites, alors vous devez tenir compte de votre serialVersionUID puisque le désérialiseur de l’object le fera correspondre à la version de l’object que possède son chargeur de classe. En savoir plus à ce sujet dans la spécification du langage Java.

    Pour comprendre la signification du champ serialVersionUID, il faut comprendre comment fonctionne la sérialisation / désérialisation.

    Lorsqu’un object de classe Serializable est sérialisé, Java Runtime associe un numéro de version série (appelé serialVersionUID) à cet object sérialisé. Au moment où vous désérialisez cet object sérialisé, Java Runtime correspond à serialVersionUID de l’object sérialisé avec le serialVersionUID de la classe. Si les deux sont égaux, alors seulement il continue avec le processus de désérialisation supplémentaire qui jette InvalidClassException.

    Nous concluons donc que pour que le processus de sérialisation / désérialisation réussisse, le serialVersionUID de l’object sérialisé doit être équivalent au serialVersionUID de la classe. Si le programmeur spécifie explicitement la valeur serialVersionUID dans le programme, la même valeur sera associée à l’object sérialisé et à la classe, indépendamment de la plate-forme de sérialisation et de désérization (par exemple, la sérialisation peut être effectuée sur une plateforme comme Windows en utilisant sun ou MS JVM et la désérialisation peuvent être sur une plate-forme Linux différente utilisant JVM Jing).

    Mais dans le cas où serialVersionUID n’est pas spécifié par le programmeur alors lors de la sérialisation \ DeSerialization de n’importe quel object, le runtime Java utilise son propre algorithme pour le calculer. Cet algorithme de calcul serialVersionUID varie d’un JRE à l’autre. Il est également possible que l’environnement dans lequel l’object est sérialisé utilise un JRE (ex: SUN JVM) et que l’environnement où se produit la désérialisation utilise Linux Jvm (zing). Dans de tels cas, serialVersionUID associé à un object sérialisé sera différent de serialVersionUID de la classe calculée lors de la désérialisation. À son tour, la désérialisation ne sera pas couronnée de succès. Donc, pour éviter de telles situations / problèmes, le programmeur doit toujours spécifier serialVersionUID de la classe Serializable.

    Ne vous embêtez pas, le calcul par défaut est vraiment bon et suffit pour 99,9999% des cas. Et si vous rencontrez des problèmes, vous pouvez, comme indiqué précédemment, introduire des UID à mesure que le besoin se présente (ce qui est hautement improbable)

    Comme pour un exemple où le serialVersionUID manquant peut causer un problème:

    Je travaille sur cette application Java EE composée d’un module Web qui utilise un module EJB . Le module Web appelle le module EJB distance et transmet un POJO qui implémente Serializable comme argument.

    POJO's classe de ce POJO's était empaquetée à l’intérieur du fichier EJB et à l’intérieur de son propre fichier JAR dans le fichier WEB-INF / lib du module Web. Ils sont en fait de la même classe, mais lorsque je conditionne le module EJB, je déballe ce pot de POJO pour le regrouper avec le module EJB.

    L’appel à l’ EJB échouait avec l’exception ci-dessous car je n’avais pas déclaré son serialVersionUID :

     Caused by: java.io.IOException: Mismatched serialization UIDs : Source (Rep. IDRMI:com.hordine.pedra.softbudget.domain.Budget:5CF7CE11E6810A36:04A3FEBED5DA4588) = 04A3FEBED5DA4588 whereas Target (Rep. ID RMI:com.hordine.pedra.softbudget.domain.Budget:7AF5ED7A7CFDFF31:6227F23FA74A9A52) = 6227F23FA74A9A52 

    J’utilise généralement serialVersionUID dans un contexte: quand je sais que cela quittera le contexte de la machine virtuelle Java.

    Je le saurais quand j’utiliserai ObjectInputStream et ObjectOutputStream pour mon application ou si je connais une bibliothèque / framework que j’utilise l’utilisera. SerialVersionID garantit que les différentes machines virtuelles Java de versions ou fournisseurs différents fonctionneront correctement ou si elles sont stockées et récupérées en dehors de la machine virtuelle, par exemple HttpSession les données de session peuvent restr même lors du redémarrage et de la mise à niveau du serveur d’applications.

    Pour tous les autres cas, j’utilise

     @SuppressWarnings("serial") 

    depuis la plupart du temps, le serialVersionUID par défaut est suffisant. Cela inclut Exception , HttpServlet .

    Les données de champ représentent certaines informations stockées dans la classe. Class implémente l’interface Serializable , donc eclipse propose automatiquement de déclarer le champ serialVersionUID . Commençons avec la valeur 1 définie ici.

    Si vous ne voulez pas que cet avertissement arrive, utilisez ceci:

     @SuppressWarnings("serial") 

    Je dois d’abord expliquer la sérialisation.
    La sérialisation permet de convertir l’object en stream, d’envoyer cet object sur le réseau OU Enregistrer dans un fichier OU enregistrer dans la firebase database pour une utilisation en lettre.

    Il existe des règles pour la sérialisation .

    • Un object est sérialisable uniquement si sa classe ou sa super-classe implémente l’interface Serializable

    • Un object est sérialisable (implémente lui-même l’interface Serializable) même si sa super-classe ne l’est pas. Cependant, la première superclasse de la hiérarchie de la classe sérialisable, qui n’implémente pas d’interface Serializable, DOIT avoir un constructeur no-arg. Si cela est violé, readObject () produira une exception java.io.InvalidClassException à l’exécution

    • Tous les types primitifs sont sérialisables.

    • Les champs transitoires (avec un modificateur transitoire) ne sont PAS sérialisés (c.-à-d. Non enregistrés ou restaurés). Une classe qui implémente Serializable doit marquer les champs transitoires des classes qui ne prennent pas en charge la sérialisation (par exemple, un stream de fichiers).

    • Les champs statiques (avec modificateur statique) ne sont pas sérialisés.

    Lorsque l’object est sérialisé JAVA Runtime Associe le numéro de version série appelé serialVersionID.

    Où nous avons besoin serialVersionID: Au cours de la désérialisation pour vérifier que l’expéditeur et le destinataire sont compatibles en ce qui concerne la sérialisation. Si le récepteur a chargé la classe avec un serialVersionID différent, alors la désérialisation se terminera par InvalidClassCastException .
    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 :.

    Essayons ceci avec un exemple.

     import java.io.Serializable; public class Employee implements Serializable { private static final long serialVersionUID = 1L; private Ssortingng empname; private byte empage; public Ssortingng getEmpName() { return name; } public void setEmpName(Ssortingng empname) { this.empname = empname; } public byte getEmpAge() { return empage; } public void setEmpAge(byte empage) { this.empage = empage; } public Ssortingng whoIsThis() { SsortingngBuffer employee = new SsortingngBuffer(); employee.append(getEmpName()).append(" is ).append(getEmpAge()).append(" years old ")); return employee.toSsortingng(); } } 

    Créer un object sérialisé

     import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class Writer { public static void main(Ssortingng[] args) throws IOException { Employee employee = new Employee(); employee.setEmpName("Jagdish"); employee.setEmpAge((byte) 30); FileOutputStream fout = new FileOutputStream("/users/Jagdish.vala/employee.obj"); ObjectOutputStream oos = new ObjectOutputStream(fout); oos.writeObject(employee); oos.close(); System.out.println("Process complete"); } } 

    Deserializ the object

     import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; public class Reader { public static void main(Ssortingng[] args) throws ClassNotFoundException, IOException { Employee employee = new Employee(); FileInputStream fin = new FileInputStream("/users/Jagdish.vala/employee.obj"); ObjectInputStream ois = new ObjectInputStream(fin); employee = (Employee) ois.readObject(); ois.close(); System.out.println(employee.whoIsThis()); } } 

    NOTE: Now change the serialVersionUID of the Employee class and save:

     private static final long serialVersionUID = **4L**; 

    And execute the Reader class. Not to execute the Writer class and you will get the exception.

     Exception in thread "main" java.io.InvalidClassException: com.jagdish.vala.java.serialVersion.Employee; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 4 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371) at com.krishantha.sample.java.serialVersion.Reader.main(Reader.java:14) 

    It would be nice if CheckStyle could verify that the serialVersionUID on a class that implements Serializable has a good value, ie that it matches what the serial version id generator would produce. If you have a project with lots of serializable DTOs, for example, remembering to delete the existing serialVersionUID and regenerate it is a pain, and currently the only way (that I know of) to verify this is to regenerate for each class and compare to the old one. This is very very painful.

    SerialVersionUID is used for version control of object. you can specify serialVersionUID in your class file also. Consequence of not specifying serialVersionUID is that when you add or modify any field in class then already serialized class will not be able to recover because serialVersionUID generated for new class and for old serialized object will be different. Java serialization process relies on correct serialVersionUID for recovering state of serialized object and throws java.io.InvalidClassException in case of serialVersionUID mismatch

    Read more: http://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html#ixzz3VQxnpOPZ

    Why use SerialVersionUID inside Serializable class in Java?

    During serialization , Java runtime creates a version number for a class, so that it can de-serialize it later. This version number is known as SerialVersionUID in Java.

    SerialVersionUID is used to version serialized data. You can only de-serialize a class if it’s SerialVersionUID matches with the serialized instance. When we don’t declare SerialVersionUID in our class, Java runtime generates it for us but its not recommended. It’s recommended to declare SerialVersionUID as private static final long variable to avoid default mechanism.

    When you declare a class as Serializable by implementing marker interface java.io.Serializable , Java runtime persist instance of that class into disk by using default Serialization mechanism, provided you have not customized the process using Externalizable interface.

    see also Why use SerialVersionUID inside Serializable class in Java

    Code : javassist.SerialVersionUID

    If you want to amend a huge number of classes which had no serialVersionUID set in the first place while maintain the compatibility with the old classes, tools like IntelliJ Idea, Eclipse fall short as they generate random numbers and does not work on a bunch of files in one go. I come up the following bash script(I’m sorry for Windows users, consider buy a Mac or convert to Linux) to make amending serialVersionUID issue with ease:

     base_dir=$(pwd) src_dir=$base_dir/src/main/java ic_api_cp=$base_dir/target/classes while read f do clazz=${f//\//.} clazz=${clazz/%.java/} seruidstr=$(serialver -classpath $ic_api_cp $clazz | cut -d ':' -f 2 | sed -e 's/^\s\+//') perl -ni.bak -e "print $_; printf qq{%s\n}, q{ private $seruidstr} if /public class/" $src_dir/$f done 

    you save the this script, say add_serialVersionUID.sh to you ~/bin. Then you run it in the root directory of your Maven or Gradle project like:

     add_serialVersionUID.sh < myJavaToAmend.lst 

    This .lst includes the list of java files to add the serialVersionUID in the following format:

     com/abc/ic/api/model/domain/item/BizOrderTransDO.java com/abc/ic/api/model/domain/item/CardPassFeature.java com/abc/ic/api/model/domain/item/CategoryFeature.java com/abc/ic/api/model/domain/item/GoodsFeature.java com/abc/ic/api/model/domain/item/ItemFeature.java com/abc/ic/api/model/domain/item/ItemPicUrls.java com/abc/ic/api/model/domain/item/ItemSkuDO.java com/abc/ic/api/model/domain/serve/ServeCategoryFeature.java com/abc/ic/api/model/domain/serve/ServeFeature.java com/abc/ic/api/model/param/depot/DepotItemDTO.java com/abc/ic/api/model/param/depot/DepotItemQueryDTO.java com/abc/ic/api/model/param/depot/InDepotDTO.java com/abc/ic/api/model/param/depot/OutDepotDTO.java 

    This script uses the JDK serialVer tool under hood. So make sure your $JAVA_HOME/bin is in the PATH.

    This question is very well documented in Effective Java by Joshua Bloch. A very good book and a must read. I will outline some of the reasons below :

    The serialization runtime comes up with a number called Serial version for each serializable class. This number is called serialVersionUID. Now there is some Math behind this number and it comes out based on the fields/methods that are defined in the class. For the same class the same version is generated every time. This number is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender’s class, then deserialization will result in an InvalidClassException.

    If the class is serializable you can also declare your own serialVersionUID explicitly by declaring a field named “serialVersionUID” that must be static, final, and of type long. Most IDE’s like Eclipse help you generate that long ssortingng.

    Each time an object is serialized the object is stamped with a version ID number for the object’s class.This ID is called serialVersionUID and it is computed based on information about the class structure. Suppose you made an Employee class and it has version id #333 (assigned by JVM),Now when you will serialize the object of that class (Suppose Employee object), JVM will assign UID to it as #333.

    Consider a situation – in the future you need to edit or change your class and in that case when you modify it, JVM will assign it a new UID (Suppose #444). Now when you try to deserialize the employee object, JVM will compare serialized object’s (Employee object) version ID(#333) with that of the class ie #444(Since it was changed). On comparison JVM will find both version UID are different and hence Deserialization will fail. Hence if serialVersionID for each class is defined by programmer itself. It will be same even if the class is evolved in future and hence JVM will always find that class is compatible with serialized object even though the class is changed. For more Info you can refer chapter 14 of HEAD FIRST JAVA.