Java Serialization, Deserialization and serialVersionUID
Find the below important points of Java Serialization, Deserialization and serialVersionUID
- Serialization is the translation of your Java object's values/states to bytes to send it over network or save it.
- The static and transient property not serialized.
- The transient property is set to null (in case of reference) or to the default value (in case of the primitive type) when the object gets deserialized.
- Serializable is a marker interface means that it is just an empty interface and using that interface will notify the JVM that this class can be made serializable. Ex - In Hibernate, to store an object we should make the class Serializable.
- Constructor is not called in deserialization process.
- The serialVersionUID property :
- It must be static, final, and long type variable. This number is calculated by the compiler based on the state of the class and the class attributes. This is the number that will help the JVM to identify the state of an object when it reads the state of the object from file.
- It is a special static variable used by the serialization and deserialization process. It's not just a static variable as others, which are definitely not serialized.
- Which is used during deserialization 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 deserialization object is different than serialization, then throws InvalidClassException.
- If serialVersionUID not specified then runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification.
- Use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members.
- Java's serialization algorithm :
- It writes out the metadata of the class associated with an instance.
- It recursively writes out the description of the superclass until it finds java.lang.object.
- Once it finishes writing the metadata information, it then starts with the actual data associated with the instance and it starts from the topmost superclass (base to derived class).
- It recursively writes the data associated with the instance, starting from the least superclass to the most-derived class (derived to base class).
- The JVM automatically-generated UID is generated based on a class name, implemented interfaces, and all public and protected members using the Secure Hash Algorithm (SHA) as defined by the National Institute of Standards.
- If serialVersionUID is not defined in a class, you can use the JDK tool serialver to generate the serialVersionUID on the old class, and explicitly set that on the new class.
- If derived class object is serialized and change the serialVersionUID of base class any how like; explicitly or metadata (class name, interface, and access specifier), deserialization won’t work for derived class.
- If you serialize the object with serialVersionUID and change any metadata (class name, interface, and access specifier) then it would not deserialized. Explicitly you have to specify the serialVersionUID of old class metadata.
- Performance - There is also a small performance benefit in explicitly declaring your serialVersionUID (because does not have to be calculated).
- What is disadvantage of specifying the serialVersionUID manually?
The generated id for the same class might differ for different compilers. So if you communicate serialized data between code compiled with different compilers, it is recommended to maintain the ids manually anyway.
Adding or removing non-transient fields doesn't make the class serialization-incompatible.
- What happens when a class is serializable but its superclass is not ?
During serialization process, if any instance variable is inherited from non serializable parent class, then JVM will ignore the normal value instead it will store the default value for that variable.
During deserialization process, if we have any non-serializable parent class, then JVM will perform following things for that non-serializable parent class.
We all know that during deserialization process, constructor should not be called. But if we have a non-serializable parent class then there will be an exception case like this. The below diagram will explain clearly about serialization and deserialization process.
- Variable Initialization will be done.
- Instance block will be executed.
- No-argument constructor will be executed.
- Why does Eclipse say I need "private static final long serialVersionUID = 1L;" when extend the Exception class?
Exception implements Serializable and eclipse warns that you have not set an serialVersionUID. It is suggestion one in order to help you serialize exceptions correctly.