1. Introduction
We often get a warning to declare serialVersionUid in our class when our class implements a Serializable interface. In this tutorial, let's see why it's required and how it affects the whole serialization/de-serialization process with a small example.
2. What is SerialVersionUid?
The serialVersionUid field represents the version no of the Serializable class, when doing the de-serialization process JVM uses this version no to identify whether the class and de-serialized objects are compatible with each other or not.
In case, if different serialVersionUid is used during the serialization and de-serialization process then JVM will be unable to match the de-serialized object with the class and hence throws InvalidClassException.
Let's understand this with an example:
Suppose we've got an Employee class with fields like fullName and email:
public class Employee{
private static final serialVersionUid = 1L;
private String fullName;
private String email;
// standard getters and setters
// parameterized constructors
}
Let's perform the serialization process and save the Employee class into a separate file:
Employee emp = new Employee("John Doe", "john@gmail.com");
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("emp.txt"))) {
oos.writeObject(emp);
oos.flush();
}
Now, let's change the serialVersionUid:
public class Employee{
private static final serialVersionUid = 2L;
//...
}
and perform the de-serialization again:
Employee emp = null;
try (ObjectInputStream empInputStream = new ObjectInputStream(new FileInputStream("emp.txt"))) {
emp = (Employee) empInputStream.readObject();
}
above code will throw the below exception and the de-serialization process will be failed because we've changed the serialVersionUid which JVM has found incompatible with the serializable class.
java.io.InvalidClassException: com.test.Employee;
3. Default SerialVersionUid
When we don't provide any serialVersionUid, then JVM automatically assigns a new serialVersionUid based on the variables, methods, and static fields we've defined in the class.
So why do we provide our own serialVersionUid?๐ค
Because if we make changes in class like if we add new fields, change any method, etc then JVM will generate a new serialVersionUid. Which may cause unexpected behavior and break the deserialization process.
That's why it's always a good practice to define serialVersionUid explicitly.
4. SerialVersionUid for Updated Class
As we've seen that serialVersionUid represents the version of class so does that mean we should update it every time we make changes in our class? No.
When to Update? Only when our new version of the class is not backward compatible and we want to break the de-serialization process.
Few examples:
- Changing the type of fields to incompatible (string to int)
- Removing existing fields
- Or when need to discontinue the old version of POJO.
And when not to update? As far as our new version of the class is backward compatible we can use the same SVU.
Few examples:
- Adding new fields in POJO.
- Changing to a DataType that is compatible with the old version (For. e.g. int to long)
- When you don't want to break de-serialization.
5. Conclusion
In this article, we've seen the serialVersionUid in detail and why it's required along with an example.
Thanks for staying till the end.
If you like this, you might also enjoy reading my other article on Java. Top 10 Eclipse Productivity Hacks for Java Developer in 2022?
Are you on Twitter? Let's connect.
Every Monday, Wednesday, and Friday, I write a thread on Java, Javascript, and Fullstack Development on Twitter.
Here's the list of my previous two Java Threads on Twitter: