Why use SerialVersionUID inside Serializable class in Java? Example (original) (raw)
Serialization and SerialVersionUID always remain a puzzle for many Java developers. I often see questions like what is this SerialVersionUID, or what will happen if I don't declare SerialVersionUID in my Serializable class? Apart from the complexity involved and rare use, one more reason for these questions is Eclipse IDE's warning against the absence of SerialVersionUID e.g. "The Serializable class Customer does not declare a static final SerialVersionUID field of type long". In this article, you will not only learn the basics of Java SerialVersionUID but also its effect during the serialization and de-serialization process.
When you declare a class as Serializable by implementing marker interface java.io.Serializable, Java runtime persists an instance of that class into a disk by using default Serialization mechanism, provided you have not customized the process using Externalizable interface.
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.
If during de-serialization, SerialVersionUID doesn't match then the process will fail with InvalidClassException as Exception in thread "main" java.io.InvalidClassException, also printing class-name and respective SerialVersionUID.
One quick solution to fix this problem is copying SerialVersionUID and declaring them as a private static final long constant in your class. In this article, we will learn about why we should use SerialVersionUID in Java and How to use serialver JDK tool for generating this ID.
If you are new to serialization, you can also see Top 10 Java Serialization Interview question to gauge your knowledge and find gap in your understanding for further reading. Similar to Concurrency and Multi-threading, Serialization is another topic, which deserve couple of reading.
Why use SerialVersionUID in Java? Example
As I said, when we don't declare SerialVersionUID, as a static, final and long value in our class, the Serialization mechanism creates it for us. This mechanism is sensitive to many details including fields in your class, their access modifier, the interface they implement and even different Compiler implementations, any change on a class or using a different compiler may result in different SerialVersionUID, which many eventually stop reloading serialized data.
It's too risky to rely on the Java Serialization mechanism for generating this id, and that's why it's recommended to declare explicit SerialVersionUID in your Serializable class. I strongly suggest to read Joshua Bloch's classic Java title, Effective Java to understand Java Serialization and issues of incorrect handling it.
By the way JDK also provides a tool called serialver, located in bin directory of JAVA_HOME folder, in my machine C:\Program Files\Java\jdk1.6.0_26\bin\serialver.exe, which can be used to generate SerialVersionUID for old classes. This is very helpful, in case you have made changes in your class, which is breaking Serialization and your application is not able to reload serialized instances.
You can simply use this tool to create SerialVersionUID for old instances and then use it explicitly in your class by declaring a private, static, final and long SerialVersionUID field. By the way, it's highly recommended, both due to performance and security reason to use customized binary format for Serialization, once again Effective Java has couple of Items, which explains benefits of custom format in great details.
How to use serialver JDK tool to generate SerialVersionUID
You can use JDK's serialver tool to generate SerialVersionUID for classes. This is particularly useful for evolving classes, it returns SerialVersionUID in format easy to copy. You can use serialver JDK tool as shown in below example :
$ serialver use: serialver [-classpath classpath] [-show] [classname...]
$ serialver -classpath . Hello Class Hello is not Serializable.
$ serialver -classpath . Hello Hello: static final long SerialVersionUID = -4862926644813433707L;
You can even use serialver tool in GUI form by running the command $ serialver -show, this will open the serial version inspector, which takes full class name and shows it's Serial version.
Summary
Now we know what is SerialVersionUID and why it's important to declare it in Serializable class, it's time to revise some of the important fact, related to Java SerialVersionUID.
1. SerialVersionUID is used to version serialized data. You can only de-serialize a class if it's SerialVersionUID matches with the serialized instance.
2. When we don't declare SerialVersionUID in our class, Java runtime generates it for us, but that process is sensitive to many class meta data including number of fields, type of fields, access modifier of fields, interface implemented by class etc. You can find accurate information in Serialization documentation from Oracle.
3. It's recommended to declare SerialVersionUID as private static final long variable to avoid default mechanism. Some IDE like Eclipse also display warning if you miss it e.g. "The Serializable class Customer does not declare a static final SerialVersionUID field of type long". Though you can disable this warning by going to Window > Preferences > Java > Compiler > Errors / Warnings > Potential Programming Problems, I suggest not to do that.