Lets look at the use of serialVersionUID in java.
1. Implement Serializable interface :
If you have ever implemented Serializable interface, you must encounter this warning message :

If you Add default serial version ID, it will be
private static final long serialVersionUID = 1L;
If you add generate serial version ID, it will be random ID generated by JVM.
e.g. private static final long serialVersionUID = 5334064047785096706L;
2. What is serialVersionUID ?
The
serialization run-time associates with each serializable class a version
number, called serialVersionUID, which is used during
deserializatioin 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 loadded 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 you do
not explicitly declare a serialVersionUID, JVM will do ti for you
automatically, based on verious aspects of your serializable class. It may very
by different version of JVM.
However, it
is strongly recommended that
all serializable classes explicitly declare serialVersionUID values, since the
default serialVersionUID computation is highly sensitive to class details that
may vary depending on compiler implementations, and can thus result in
unexpected
InvalidClassException
s during
deserialization. Therefore, to guarantee a consistent serialVersionUID value
across different java compiler implementations, a serializable class must
declare an explicit serialVersionUID value. It is also strongly advised that
explicit serialVersionUID declarations use the private
modifier
where possible, since such declarations apply only to the immediately declaring
class--serialVersionUID fields are not useful as inherited members.3. serialVersionUID Example :
StudentBean.java
A serializable class with a serialVersionUID of 1L and auto-generated serialVersionUID of 5334064047785096706L as commented.
import java.io.Serializable;
public class StudentBean implements Serializable {
private static final long serialVersionUID = 1L;
// private static final long serialVersionUID = 5334064047785096706L;
private Integer studentId;
private String firstname;
private String lastname;
private String studentClass;
public Integer getStudentId() {
return studentId;
}
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getStudentClass() {
return studentClass;
}
public void setStudentClass(String studentClass) {
this.studentClass = studentClass;
}
}
SerializeStudentBean.java
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class SerializeStudentBean {
public static void main(String args[])
{
StudentBean
student = new StudentBean();
student.setStudentId(25);
student.setFirstname("James");
student.setLastname("Johnson");
student.setStudentClass("IX");
try {
FileOutputStream fout = new FileOutputStream("c:\\student.ser");
ObjectOutputStream oos = new
ObjectOutputStream(fout);
oos.writeObject(student);
oos.close();
System.out.println("StudentBean
has been serialized.");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
DeserializeStudentBean.java
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class DeserializeStudentBean {
public static void main(String args[])
{
StudentBean
student;
try {
FileInputStream
fin = new FileInputStream("c:\\student.ser");
ObjectInputStream
ois = new
ObjectInputStream(fin);
student
= (StudentBean) ois.readObject();
ois.close();
System.out.println("StudentBean
has been deserialized.");
System.out.println("ID :- "+student.getStudentId());
System.out.println("First Name :-
"+student.getFirstname());
System.out.println("Last Name :-
"+student.getLastname());
System.out.println("Class :-
"+student.getStudentClass());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Output of DeserializeStudentBean.java
StudentBean has been deserialized.
Student ID :- 25
Student First Name :- James
Student Last Name :- Johnson
Student Class :- IX
In StudentBean,java, change serialVersionUID to 2L and compile it again, and run DeserializeStudentBean.java.
java.io.InvalidClassException: StudentBean; local class incompatible:
stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
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
DeserializeStudentBean.main(DeserializeStudentBean.java:12)
The reason for this InvalidClassException is you write a serialization class with serialVersionUID=1L, but you are trying to retrieve it back with modified serialVersionUID=2L.
The serialVersionUID have to match during the serialization and deserialization process.4. What is wrong with the default serialVersionUID?
If no serialVersionUID is declared, JVM will
use its own algorithm to generate a default SerialVersionUID,
The default
serialVersionUID computation is highly sensitive to class details and may vary
from different JVM implementation, and result in an unexpected InvalidClassExceptions during the
deserialization process.
5. How to generate serialVerionUID ?
You can use JDK serialver or Eclipse IDE to generate serialVersionUID automatically.
6. Conclusion
SUN is highly recommended developers to declare the serialVersionUID in order to avoid the different JVM issue listed above, however I rather recommend you should understand what is serialization, how serialVersionUID implement version control and why your class need to use serialization. Understand the serialVersionUID concept is better than blindfold to any recommendation.
0 comments :
Post a Comment