As far as my understanding goes constructor of class whose Object is serialized is not called but the no-arg constructor of 1st non serializable constructor. Now consider following code
public class SerializeDemo implements Serializable {
private String name;
int age; //default 0
public SerializeDemo(String name, boolean setAge){
this.name = name;
if(setAge){
this.age = 18;
}
}
@Override
public String toString() {
return "Name is " + name + " and age is " + age;
}
public static void main(String args[]) throws IOException, ClassNotFoundException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("//home//aniket//Desktop//serializedObjects.txt")));
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("//home//aniket//Desktop//serializedObjects.txt")));
SerializeDemo sd = new SerializeDemo("Test",true);
System.out.println("Before Serialization : " + sd);
oos.writeObject(sd);
SerializeDemo sdCopy = (SerializeDemo)ois.readObject();
System.out.println("After Deserialization : " + sdCopy);
}
}
and the output is(as expected)
Before Serialization : Name is Test and age is 18
After Deserialization : Name is Test and age is 18
Now the the non serializable super class having no-arg constructor is Object(Correct me if I am wrong). So basically SerializeDemo constructor is not called.
Now when the Object is created during deserialization it will try to rebuild the instance state. So it will set age to 18.
Question is how?
I have deliberately not provided the setter. Nor as per above discussion it's constructor is called. So how is it set?(Same goes for name as well)
You can take a look at ObjectInputStream
source code. It uses reflection, it creates an object, reads fields from stream, and sets object's fields using reflection. You can run your code in a debugger and go step by step exactly to the line where age is set.
Now the the non serializable super class having no-arg constructor is Object.
Correct.
So basically SerializeDemo constructor is not called.
Correct.
Now when the Object is created during deserialization it will try to rebuild the instance state. So it will set age to 18.
Correct.
Question is how?
Reflection ... with access checks turned off.
The class descriptor in the serialized class gives the name and type of all of the serialized fields. The Class
object defines Field
objects for the actual class. The deserialization code matches the available serialized fields to the Field
objects, and then uses Field.set(...)
methods to set the field values.
(In fact, this is an implementation detail, but that's my understanding of how it works in current generation JVMs. You can always check the source code ...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With