What is use of serialVersionUID

Reference URL : During object serialization, the default Java serialization mechanism writes the metadata about the object, which includes the class name, field names and types, and superclass. This class definition is stored as a part of the serialized object. This stored metadata enables the deserialization process to reconstitute the objects and map the stream data into the class attributes with the appropriate type
Everytime an object is serialized the java serialization mechanism automatically computes a hash value. ObjectStreamClass’s computeSerialVersionUID() method passes the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns a hash value.The serialVersionUID is also called suid.
So when the serilaize object is retrieved , the JVM first evaluates the suid of the serialized class and compares the suid value with the one of the object. If the suid values match then the object is said to be compatible with the class and hence it is de-serialized. If not InvalidClassException exception is thrown.

Changes to a serializable class can be compatible or incompatible. Following is the list of changes which are compatible:

  • Add fields
  • Change a field from static to non-static
  • Change a field from transient to non-transient
  • Add classes to the object tree

List of incompatible changes:

  • Delete fields
  • Change class hierarchy
  • Change non-static to static
  • Change non-transient to transient
  • Change type of a primitive field

So, if no suid is present , inspite of making compatible changes, jvm generates new suid thus resulting in an exception if prior release version object is used .
The only way to get rid of the exception is to recompile and deploy the application again.

If we explicitly metion the suid using the statement:

private final static long serialVersionUID = <integer value>

then if any of the metioned compatible changes are made the class need not to be recompiled. But for incompatible changes there is no other way than to compile again.


Reference URL : If you ever implemented Serializable interface, you must encounter this warning message

The serializable class xxx does not declare a static final serialVersionUID 
field of type long

So…what is serialVersionUID?

The serialVersionUID is used as a version control in a Serializable class. If you do not explicitly declare a serialVersionUID, JVM will did it for you automatically, based on various aspects of your Serializable class, as describe in the Java(TM) Object Serialization Specification.

SerialVersionUID Example

The above statement is a bit hard to understand at the beginning (as least i did), let start an example to understand how Serializable class use SerialVersionUID to implement version control.

1. Address.java

A serializable class with a serialVersionUID of 1L.

import java.io.Serializable;

public class Address implements Serializable{

	   private static final long serialVersionUID = 1L;

	   String street;
	   String country;

	   public void setStreet(String street){
		   this.street = street;
	   }

	   public void setCountry(String country){
		   this.country = country;
	   }

	   public String getStreet(){
		   return this.street;
	   }

	   public String getCountry(){
		   return this.country;
	   }

	   @Override
	   public String toString() {
    	   return new StringBuffer(" Street : ")
    	   .append(this.street)
    	   .append(" Country : ")
    	   .append(this.country).toString();
	   }
}

2. WriteObject.java

A simple class to write / serialize the Address object into a file – “c:\\address.ser”.

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

public class WriteObject{

	public static void main (String args[]) {

	   Address address = new Address();
	   address.setStreet("wall street");
	   address.setCountry("united state");

	   try{

	        FileOutputStream fout = new FileOutputStream("c:\\address.ser");
		ObjectOutputStream oos = new ObjectOutputStream(fout);
		oos.writeObject(address);
		oos.close();
		System.out.println("Done");

	   }catch(Exception ex){
		   ex.printStackTrace();
	   }
	}
}

3. ReadObject.java

A simple class to read / deserialize the Address object from file – “c:\\address.ser”.

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

public class ReadObject{

   public static void main (String args[]) {

	   Address address;

	   try{

		   FileInputStream fin = new FileInputStream("c:\\address.ser");
		   ObjectInputStream ois = new ObjectInputStream(fin);
		   address = (Address) ois.readObject();
		   ois.close();

		   System.out.println(address);

	   }catch(Exception ex){
		   ex.printStackTrace();
	   }
   }
}

Testing

Let do some testing to demonstrate the use of serialVersionUID.

1. Same serialVersionUID

Same serialVersionUID , there are no problem during deserialization process

javac Address.java
javac WriteObject.java
javac ReadObject.java
java WriteObject
java ReadObject
Street : wall street Country : united state

2. Different serialVersionUID

In Address.java, change the serialVersionUID to 2L (it was 1L), and compile it again.

javac Address.java
java ReadObject
java.io.InvalidClassException: Address; local class incompatible:
stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
        ...
        at ReadObject.main(ReadObject.java:14)

The “InvalidClassException” will raise, because you write a serialization class with serialVersionUID “1L” but try to retrieve it back with updated serialization class, serialVersionUID “2L”.

The serialVersionUID have to match during the serialization and deserialization process.


Suppose you have a class which you serialized it and stored in persistence and later modified that class to add a new field. What will happen if you deserialize the object already serialized?
–     It depends on whether class has its own serialVersionUID or not. As we know from above question that if we don’t provide serialVersionUID in our code java compiler will generate it and normally it’s equal to hash code of object. by adding any new field there is chance that new serialVersionUID generated for that class version is not the same of already serialized object and in this case Java Serialization API will throw java.io.InvalidClassException and this is the reason its recommended to have your own serialVersionUID in code and make sure to keep it same always for a single class.

What is serialVersionUID? What would happen if you don’t define this?
– SerialVersionUID is an ID which is stamped on object when it get serialized usually hashcode of object, you can use tool serialver to see serialVersionUID of a serialized object .  serialVersionUID is used for version control of object. you can specify serialVersionUID in your class file also.  Consequence of not specifying  serialVersionUID is that when you add or modify any field in class then already serialized class will not be able to recover because serialVersionUID generated for new class and for old serialized object will be different. Java serialization process relies on correct serialVersionUID for recovering state of serialized object and throws java.io.InvalidClassException in case of serialVersionUID mismatch.


NameStore.java

package com.serializable_expl;

import java.io.Serializable;
public class NameStore implements Serializable
{

    /**
    *
    */
    private static final long serialVersionUID = 9024561712115377771L;

    private String firstName;
    private transient String middleName;
    private String lastName;

    public NameStore (String fName, String mName, String lName)
    {
        this.firstName = fName;
        this.middleName = mName;
        this.lastName = lName;
    }

    public String toString()
    {
        StringBuffer sb = new StringBuffer(40);
        sb.append("First Name : ");
        sb.append(this.firstName);
        sb.append("   Middle Name : ");
        sb.append(this.middleName);
        sb.append("   Last Name : ");
        sb.append(this.lastName);
        return sb.toString();
    }

}

TransientExample.java

package com.serializable_expl;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class TransientExample
{

    public static void main(String args[]) throws Exception 
    {
        NameStore nameStore = new NameStore("Steve","Middle","Jobs");
        ObjectOutputStream o = 
                 new ObjectOutputStream(new FileOutputStream("nameStore"));
        // writing to object
        o.writeObject(nameStore);
        System.out.println("Serialization of Object is done..!");
        o.close();

        // reading from object
        ObjectInputStream in =
                   new ObjectInputStream(new FileInputStream("nameStore"));
        NameStore nameStore1 = (NameStore)in.readObject();

        System.out.println(nameStore1);
        System.out.println("DeSerialization of Object is done..!");

        in.close();
    }
}
Output  :-

Serialization of Object is done..!
First Name : Steve   Middle Name : null   Last Name : Jobs
DeSerialization of Object is done..!

If you need more in detail Examples then refer below mention URL :  Reference URL



Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s