Sunday 21 September 2014

serialVersionUID

serialVersionUID is a 64 bit number used to uniquely identify a class. It is used in serialization and deserialization process. Whenever you serialize an object, serialVersionUID of the class also written to the file. Whenever you deserialize this object, java run time extract this serialVersionUID value from the serialized data and compare the same value associate with the class. If both are not match, then 'java.io.InvalidClassException' will be thrown.

How to define serialVersionUID
access-modifier static final long serialVersionUID = 1L;

Example
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class SerializeEmployee {
    static void serializeEmployee()throws Exception{
          /* Serialize object */
        FileOutputStream fos = new FileOutputStream("ser.out");
        ObjectOutputStream out = new ObjectOutputStream(fos);
        Employee emp = new Employee(1, "Krishna", "Arjun");
        out.writeObject(emp);
    }
}

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class DeserializeEmployee {
    static void deserializeEmployee()throws Exception{
         /* Deserialize object */
        FileInputStream fis = new FileInputStream("ser.out");
        ObjectInputStream in = new ObjectInputStream(fis);
        Employee emp1 = (Employee)in.readObject();
        
        System.out.println(emp1.id + " " + emp1.firstName +" " +emp1.lastName);
    }
}

import java.io.*;

public class Employee implements Serializable{
    
    private static final long serialVersionUID = 1L;
    
    int id;
    String firstName;
    String lastName;
    
    Employee(int id, String firstName, String lastName){
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }
    
    public static void main(String args[]) throws Exception{
           SerializeEmployee.serializeEmployee();
           DeserializeEmployee.deserializeEmployee();
    }
}

Output
1 Krishna Arjun

Above program defines serialVersionUID as 1, now will add two changes to Employee.java and recompile and rerun.

Change1 : set serialCersionUID to other than 1
private static final long serialVersionUID = 2L;

Change 2: Comment 'SerializeEmployee.serializeEmployee();'

import java.io.*;

public class Employee implements Serializable{
    
    private static final long serialVersionUID = 2L;
    
    int id;
    String firstName;
    String lastName;
    
    Employee(int id, String firstName, String lastName){
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }
    
    public static void main(String args[]) throws Exception{
           //SerializeEmployee.serializeEmployee();
           DeserializeEmployee.deserializeEmployee();
    }
}

Now try to run the above program, runtime throws InvalidClassException like below.

Exception in thread "main" java.io.InvalidClassException: Employee; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:621)
 at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
 at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
 at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
 at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
 at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
 at DeserializeEmployee.deserializeEmployee(DeserializeEmployee.java:9)
 at Employee.main(Employee.java:19)
Java Result: 1


Is it necessary to define serialVersionUID for every serializble class ?
It is not necessary to explicitly define serialVersionUID, but it is recommended.
If your program don't define serialVersionUID, then the serialization runtime creates serialVersionUID and associate the value to it. The serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class like fields, methods etc.,, as described in the Java(TM) Object Serialization Specification.

Why Specifying serialVersionUID explicitly recommended ?
Ofcourse, the serialization runtime will calculate a default serialVersionUID value for your class, but it is highly 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.




                                                             Home

No comments:

Post a Comment