What is serialVersionUID ?

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 InvalidClassExceptions 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.
Share on Google Plus

0 comments :

Post a Comment