ObjectInputStream is = new ObjectInputStream(new FileInputStream("test.ser"));
TestClass tc = (TestClass)is.readObject();
I get the object of TestClass after deserialization but TestClass default constructor is not called. As per my understanding there are two ways to create object i.e either with new operator or TestClass.class.newInstance(). Both calls the default constructor.
Looks like deserialization process creates the object not with about two methods thats why default constructor is not called. Question is how deserialization creates the object ?
Another point is if TestClass extends BaseTestClass and BaseTestClass does not implements serialization , constructor of BaseTestClass is called but not TestClass. Why so ? I am sure there will be some logical reason behind it. But i am not getting it?
It's worth reading Java Object Serialization Specification: 3 - Object Input Classes where readObject method is described in details along with step by step explanation.
An instance of the class is allocated. The instance and its handle are added to the set of known objects.
The contents restored appropriately:
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 the normal case, the version of the class that wrote the stream will be the same as the class reading the stream. In this case, all of the supertypes of the object in the stream will match the supertypes in the currently-loaded class.
If the version of the class that wrote the stream had different supertypes than the loaded class, the ObjectInputStream must be more careful about restoring or initializing the state of the differing classes.
It must step through the classes, matching the available data in the stream with the classes of the object being restored. Data for classes that occur in the stream, but do not occur in the object, is discarded.
For classes that occur in the object, but not in the stream, the class fields are set to default values by default serialization.
For externalizable objects, the no-arg constructor for the class is run and then the readExternal method is called to restore the contents of the object.
Sample code to understand fist point For serializable objects, the no-arg constructor for the first non-serializable supertype is run.
Sample code;
class TestClass1 {
public TestClass1() {
System.out.println("TestClass1");
}
}
class TestClass2 extends TestClass1 implements Serializable {
public TestClass2() {
System.out.println("TestClass2");
}
}
public static void main(String[] args) throws Exception {
System.out.println("Object construction via calling new keyword");
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("resources/dummy.dat"));
out.writeObject(new TestClass2());
System.out.println("Object construction via readObject method");
ObjectInputStream is = new ObjectInputStream(new FileInputStream("resources/dummy.dat"));
TestClass2 tc = (TestClass2) is.readObject();
}
output:
Object construction via calling new keyword
TestClass1
TestClass2
Object construction via readObject method
TestClass1
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