Why default constructor is not called during Deserialization process in Java.

Why default constructor is not called during deserialization process. OR
Why Deserialization does not invoke constructor in Java.


Let see why default constructor is not called during deserialization in java and how are the constructors invoked during serialization and deserialization.

Java serialization specification says, "For serializable objects, the no-arg constructor for the first non-serializable supertype is run". Lets see what this is all about and understand it with example.
 
See below diagram to get overview of Serialization and Deserialization process.


Before looking into this post, I recommend to first look at below post to understand how Serialization and Deserialization works in Java.
How are Constructors invoked during Serialization and Deserialization process in Java.
 


Why default constructor is not called during deserialization process in java?

Think in this way, what is the need of constructor?
Constructor initializes the object variables with either default values or values which is assigned inside constructor.

Let us understand with small example and things will be more clear.
package javabypatel;

class Temprature implements Serializable{
  public int temprature; 
  public Date date;

  public Temprature(){
    temprature = 10; 
    date = new Date() //initialize with today's date
  }
}

public class MainClass {

 public static void main(String[] args){
  try {

   /****** SERIALIZATION ******/
   Temprature t = new Temprature();
   t.temprature = 16; //Today's temprature is 16.

   ByteArrayOutputStream baos = new ByteArrayOutputStream();
   ObjectOutputStream oos = new ObjectOutputStream(baos);

   System.out.println("Serializing Object...");
   oos.writeObject(t);
   oos.flush();
   baos.flush();
   oos.close();
   baos.close();

   /****** DE-SERIALIZATION ******/
   ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
   ObjectInputStream ois = new ObjectInputStream(bais);
   System.out.println("Deserializing Object...");
   
   Temprature deserializedTemprature = (Temprature)ois.readObject();
   System.out.println("Temprature is :"+deserializedTemprature.temprature);

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

}
Output :
Serializing Object...
Deserializing Object...
Temprature is : 16


Explanation:
Temprature t = new Temprature();
t.temprature = 16; //Today's temprature is 16.

What we did above is created a Temprature object "t", which by default initializes with today's date say(11th May, 2017) and initial temprature as 10 in constructor.
But by end of the day we found that average temprature for today's date was 16, so we override the value 10 to 16 and persists it in File.

After 1 month, I want to see what was temprature on "11th May, 2017". I need to reconstruct the Temprature object back to see the temprature value on that day.
So to deserialize back, what we did is,

Temprature t1 = (Temprature)ois.readObject(); 

Actual question starts now, will default constructor of Temprature will be called or not?
No. Default constructor of Temprature class will not be called during deserialization process.

Java specification says,

"For serializable objects, the no-arg constructor for the first non-serializable supertype is run. For serializable classes, the fields are initialized to the default value appropriate for its type. Then the fields of each class are restored by calling class-specific readObject methods, or if these are not defined, by calling the defaultReadObject method. Note that field initializers and constructors are not executed for serializable classes during deserialization."
In simple words, it will first check whether Temprature class is marked as Serializable, in our case, yes it is, because it implements Serializable interface.

Now, it check upwards in inheritance hierarchy, whether super class of Temprature class is marked as Serializable, in our case, super class of Temprature class is default Object class.
So it will check whether Object class implements Serializable interface. No. it doesn't. Java stops searching here.

Now, it comes to know Temprature is the only class for which object state need to be restored back and state of no other class up the hierarchy needs to be restored.

So, Java creates the object of Object class first by calling its no-argument default constructor and with the help of reflection, it creates the object of Temprature class.

For creating Temprature object it will not call constructor of Temprature class instead it uses ReflectionFactory class internally for creating the object, which initializes the fields of Temprature object with default values according to variable type first and later it reinitialize the variables with the value present in deserialized stream to restore back the original value which was present at the time of Serialization.

Now, the question is why it does like this and not called constructor of Temprature instead?

If it calls the constructor of Temprature class then it defeats the purpose of Constructor, which says Constructor constructs the object with default values or values provided inside constructor.
For restoring the temprature 16 of date "11th May, 2017", if it calls constructor then temprature value will be 10 and date will be "11th June, 2017" (as we are deserializing after 1 month) which is wrong.

To avoid initializing variables with default values and preserve the actual state of variable, it doesn't call default constructor of object.

Conclusion:

So what Java does during Deserialization process is, it starts checking which class object state needs to be preserved and for identifying this it looks for class implements Serializable interface and where it first find a class which doesn't implements Serializable interface, it calls constructor of that class because It doesn't care if value of that class will be overriden because it is already marked non serializable. For class which marked Serializable, it constructs object using ReflectionFactory and retsore value of that class from deserializing stream.

You may also like to see


Important Java Multithreading Interview Questions-Answers

How is ambiguous overloaded method call resolved in java?

Exception Handling Interview Question-Answer

Type Casting Interview Questions In Java

Method Overriding rules in Java

Java Interface interview questions and answers

Count number of Set Bits in Integer. 

Check if number is Power of Two. 

Find all subsets of a set (Power Set). 

Skyline Problem in Java. 

Find Minimum length Unsorted Subarray, Sorting which makes the complete array sorted 

Count trailing zeros in factorial of a number 

Enjoy !!!! 

If you find any issue in post or face any error while implementing, Please comment.

Post a Comment