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{
MySerializable(){
public class MySender {
public class MyReceiver {
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 Q2: static 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.
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
Post a Comment