Most ignored concept in java but very important from interview point of view : SerialVersionUID

Believe me or not, serialVersionUID is the most ignored concept in java. But as you get familiar with it, you will get to know how important and how powerful this concept is.

So, lets deep dive to understand the serialVersionUID concept.


Prerequisite

You need to have prior knowledge of serialization and deserialization to understand the serialVersionUID concept better. 


What is serialVersionUID?

When we serialize an object, JVM generates one unique identifier for serializable class. Which is used at the time of deserialization to verify the sender (who serializes the object) and the receiver (who deserializes the object) have loaded the same compatible serializable class versions at their side? This unique identifier is called serialVersionUID.


How JVM calculates default serialVersionUID?

JVM uses various aspects of the class to calculate the serialVersionUID like class name, implemented interface, all members of that class, etc. The calculation of default  serialVersionUID is very much sensitive to all these aspects of the class. Thus, any small change in any of these may change the value of serialVersionUID calculated by JVM.

Check here the detailed algorithm used by JVM to calculate serialVersionUID.


How serialVersionUID works?

  • At the time of serialization, sender side JVM generates the serialVersionUID for serializable class loaded at the sender's side and serializes it along with other instance variables.
  • At the time of deserialization, receiver side JVM fetches that serialized serialVersionUID  and compares it with the receiver side serialVersionUID,  calculated based on its local version of the serializable class.
  • If both match, then only deserialization takes place. Otherwise, it fails with runtime exception saying “InvalidClassException” at the receiver side.

Problems with JVM generated default serialVersionUID

There are some major problems with the default serialVersionUID generated by JVM.

  • Both sender and the receiver should use the same JVM (with respect to version and vendor of JVM) as different JVM may generate different serialVersionUID for the same class version, which may lead to the failure at the time of deserialization.
  • The default serialVersionUID is very sensitive to the class properties. Any slight change in any of them may change the value of serialVersionUID.  So, both, the sender and receiver should have exactly the same version of the class file. Any small change in the class file after serialization may cause a failure at the time of deserialization.
  • To generate serialVersionUID, internally JVM may use a complex algorithm that may create a performance problem.

These are the major problem of relying on default serialVersionUID generated by JVM. But don't lose hope. Every problem has a solution. So is this.


Solution

We can overcome the above problems by defining our own serialVersionUID externally. JVM generates default serialVersionUID if the programmer doesn’t provide it externally. It's always recommended to define external serialVersionUID, instead of relying on the default one created by JVM. Below is the syntax to define serialVersionUID externally.

             any_modifier static final long serialVersionUID = 1L;

Below code snippet shows, how we can define serialVersionUID externally.

 

public class MySerializable implements Serializable{

     public static final long serialVersionUID = 111111L;
     String name = null;
     String paltform = null;
     int version;

     MySerializable(){

           name = "Other blog";
           paltform = "Unknown";
           version = 0;
     }
}

 

public class MySender {

     public static void main(String[] args) throws FileNotFoundException, IOException {
           MySerializable mySerializable = new MySerializable();
           mySerializable.name = "DeepDive91";
           mySerializable.paltform = "Java";
           mySerializable.version = 1;
           ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("DeepDive91.txt"));
           oos.writeObject(mySerializable);
           System.out.println("Serialization completed!! ");
     }
 }

 

public class MyReceiver {

     public static void main(String[] args) throws ClassNotFoundException, IOException {
           MySerializable mySerializable = new MySerializable();
           ObjectInputStream ois = new ObjectInputStream(new FileInputStream("DeepDive91.txt"));
           mySerializable = (MySerializable)ois.readObject();
           System.out.println("Deserialization completed!! ");
           System.out.println("Blog name= "+mySerializable.name);
           System.out.println("Platform= "+mySerializable.paltform);
           System.out.println("Version= "+mySerializable.version);
     }
} 

Interview Quiz

Based on the above explanation, the interviewer may ask you some tricky questions like below.

Interviewer Q1: Is it compulsory to declare serialVersionUID as static? why?

Your Answer: Yes, compulsorily serialVersionUID should declare as static because of the below reasons.

  • Deserialization means, constructing or creating an object from the serialized form. Whereas, the main purpose of serialVersionUID is to validate the class version right before deserialization that class's object. At the time of class validation, there is no object created or deserialized. So that's why serialVersionUID should always be static (as we know, the static members get created in the very beginning, when JVM loads the class) and not instance variable, so that JVM can use it to validate the deserialization, without having any object.
  • Static members are class level members and the purpose of serialVersionUID is to maintain the identifier for each class version. And that's why it declared as static, to bound it to class level.

 

Interviewer Q2static member does not participate in the serialization, then how JVM serializes serialVersionUID which is compulsorily static?

Your Answer: It's true that we cannot serialize static members. But, the serialVersionUID is one and only exceptional case in java. Even though it's static,  but JVM treats it specially and serializes it along with other instance variables. But to get serialVersionUID serialized, it must be declared static, final, and of type long only. Any change in this syntax, won't allow it to be serialized.

                    static final long serialVersionUID


Conclusion

serialVersionUID is the unique identifier, that is serialized along with instance variables in serialization and used at the time of deserialization to validate the class version compatibility.

Hope this article has helped you to understand the serialVersionUID concept better. If you have any questions about this topic you can write it in the comments section. I will try to answer your queries ASAP.

See you in the next post. Till then keep reading.

Comments

Popular posts from this blog

Can we define explicit constructor for an anonymous inner class?

Why we can not throw exception from Thread’s run method?

How does thread's run method get invoked??