Using serialVersionUID
This tutorial explains the importance of versioning Serializable objects using serialVersionUID.
1. Introduction
In Java whenever a class implements java.io.Serializable we get a warning saying.
“The serializable class Student does not declare a static final serialVersionUID field of type long”
when we auto fix this warning by generating a default serial version, eclipse adds the the below lines.
2. POJO Class
Lets create a simple serializable POJO class Student.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package com.heapcode.java; public class Student implements java.io.Serializable{ private static final long serialVersionUID = 1L; private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } |
3. Main Class to serialize and de-serialize the above POJO
The below class two methods one which creates a new Student object, populates with values and serializes, whereas other method reads the serialized object and prints the fields.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.heapcode.java; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class Serializor { public static void main(String[] args) throws IOException, ClassNotFoundException { Serializor serializor = new Serializor(); serializor.serialize(); serializor.deSerialize(); } public void serialize() throws IOException{ Student student = new Student(); student.setId(1); student.setName("HeapCode"); FileOutputStream fileOutputStream = new FileOutputStream("/Users/msampath/Stude.ser"); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); objectOutputStream.writeObject(student); System.out.println("Serialization complete."); objectOutputStream.close(); fileOutputStream.close(); } public void deSerialize() throws IOException, ClassNotFoundException{ FileInputStream fileInputStream = new FileInputStream("/Users/msampath/Stude.ser"); ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream); Student student = (Student) objectInputStream.readObject(); System.out.println("De-serialization complete."); System.out.println(student.getId()); System.out.println(student.getName()); objectInputStream.close(); fileInputStream.close(); } } |
4. First Run
5. Change Serial Version and de serialize.
Lets change the serialVersionUID in the Student.java
1 2 3 4 5 6 7 8 |
package com.heapcode.java; public class Student implements java.io.Serializable{ private static final long serialVersionUID = 2L; private int id; ........ |
next in the Serializor.java lets comment the line which serializes and try to de-serialize the Student object previously serialized.
1 2 3 4 5 6 7 8 |
public class Serializor { public static void main(String[] args) throws IOException, ClassNotFoundException { Serializor serializor = new Serializor(); //serializor.serialize(); //This line is commented serializor.deSerialize(); } ...... |
6. Second Run
When we run the same program again after making the above changes, we get the below exception
1 2 3 4 5 6 7 8 9 |
Exception in thread "main" java.io.InvalidClassException: com.heapcode.java.Student; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:570) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1601) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:349) at com.heapcode.java.Serializor.deSerialize(Serializor.java:32) at com.heapcode.java.Serializor.main(Serializor.java:14) |
7. Conclusion
- The second run above failed because the serialVersionUID changed after the serialization had taken place.
- Usually in Distributed Systems the system which serializes might not always be the one to de-serialize it, for example. a server might serialize an object and then a client might de-serialize it. Hence its of utmost importance to add serialVersionUID to all Serializable classes.
- If we dont specify a serialVersionUID then the JVM automatically adds one and the algorithm for generating the same is different across different JDKs example, Sun JDK and Open JDK might generate a different serialVersionUID for the same Class.
- Its always a good practice to start the serialVersionUID from 1L whenever we modify the class we increment this number by 1 so that it fails in case the other person doesn’t have the latest version.
I hope this has been useful for you and I’d like to thank you for reading. If you like this article, please leave a helpful comment and share it with your friends.
detailed explanation… thanks Manju…
welcome Sundar!
Hi Manju it’s excellent very informative Thanks Manju
Thanks Shaikkh!
Wow, Short and precise explanation. Keep it up Manju…!
Thanks Dinesh!