Here I will discuss the importance of the variable serialVersionUID which are used in Serializable classes.
Below is an example that will make you understand the exact use of the variable.
Example Code
Employee.java
package com.jbt;
import java.io.Serializable;
public class Employee implements Serializable
{
public String firstName;
public String lastName;
private static final long serialVersionUID = 5462223600l;
}
SerializaitonClass.java (This class will be used to serialize)
package com.jbt;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializaitonClass {
public static void main(String[] args) {
Employee emp = new Employee();
emp.firstName = "Vivekanand";
emp.lastName = "Gautam";
try {
FileOutputStream fileOut = new FileOutputStream("./employee.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(emp);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in ./employee.txt file");
} catch (IOException i) {
i.printStackTrace();
}
}
}
DeserializationClass.java (This class will be used to deserialize )
package com.jbt;
import java.io.*;
public class DeserializationClass {
public static void main(String[] args) {
Employee emp = null;
try {
FileInputStream fileIn = new FileInputStream("./employee.txt");
ObjectInputStream in = new ObjectInputStream(fileIn);
emp = (Employee) in.readObject();
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
return;
} catch (ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
return;
}
System.out.println("Deserializing Employee...");
System.out.println("First Name of Employee: " + emp.firstName);
System.out.println("Last Name of Employee: " + emp.lastName);
}
}
Now execute “SerializationClass.java” and then “DeserializationClass.java”. It will first create a file with Employee object’s state and then while de-serialization it creates an object from the same file. The output will be something like below.
Serialized data is saved in ./employee.txt file
Deserializing Employee...
First Name of Employee: Vivekanand
Last Name of Employee: Gautam
Now let’s try and remove “serialVersionUID” variable from Employee.java file and again run “SerializationClass.java” file. It will create “employee.txt” file again with the object’s state. Now let’s add a new variable in Employee class suppose String Address.
Employee.java
package com.jbt;
import java.io.Serializable;
public class Employee implements Serializable
{
public String firstName;
public String lastName;
public String Address;
//Variable is commented
// private static final long serialVersionUID = 5462223600l;
}
Now run “DeserializationClass.java” and see the output.Booom
java.io.InvalidClassException: com.jbt.Employee; local class incompatible: stream classdesc serialVersionUID = 5462223600, local class serialVersionUID = -3607530122250644586
at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at com.jbt.DeserializationClass.main(DeserializationClass.java:11)
It will throw an incompatible exception. Because the given class Employee.java was changed in between serialization and de-serialization process. Hence the system failed to identify that it is still the same class. To make our system understand that it is the same class you have to make use of serialVersionUID variable inside a class.
You can try to follow the above steps but keep serialVersionUID intact and see the output. De-serialization process will work without any issue.
Bullet Points
- Defining a serialVersionUID field in a serializable class is not mandatory.
- If a serializable class has an explicit serialVersionUID then this field should be of type long and must be static and final.
- If there is no serialVersionUID field defined explicitly then serialization runtime will calculate default value for that class. The value can vary based on compiler implementation. Hence it is advisable to define serialVersionUID.
- It is advised to use private access modifier for serialVersionUID.
- The different class can have the same serialVersionUID.
- Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is waived for array classes.
- If there is a difference between serialVersionUID of loaded receiver class and corresponding sender class then InvalidClassException will be thrown.
- You should use different serialVersionUID for the different version of the same class if you want to forbid serialization of a new class with an old version of the same class.
@SuppressWarnings(“serial”)
If you do not provide serialVersionId in a class which is supposed to be serialized then the compiler will give warning messages about the same. If you want to override this warning you can use given annotation. Once used, the compiler will stop complaining about the missing serialVersionUID.
7 means to raise your productivity and also amazingness!
nice explanation,easy to understand for beginners as well.
good explanation!!
Don’t even need to modify the Employee class, by commenting serialVersionUID before de-serialization itself it would start throwing ‘InvalidClassException’ exception.
good explanation.
nice explanation
Nice website …
Very Nice Xplanation.
Its worth reading.