Why is constructor of the Food and Fruit class called when I deserialize where as the constructor of SkinFruit and Banana2 is not called in the below example?
Suppose I have following class hierarchy
class Food{
public Food() { System.out.println("1"); }
}
class Fruit extends Food {
public Fruit() { System.out.print("2"); }
}
class SkinFruit extends Fruit implements Serializable{
SkinFruit() { System.out.print("3"); }
}
public class Banana2 extends SkinFruit {
private static final long serialVersionUID = 1L;
int size = 42;
public static void main(String [] args) {
Banana2 b = new Banana2();
FileOutputStream fost;
try {
fost = new FileOutputStream(new File("d:/testbanana.ser"));
ObjectOutputStream oostr= new ObjectOutputStream(fost);
oostr.writeObject(b);
oostr.flush();
oostr.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
try {
FileInputStream fin= new FileInputStream(new File("d:/testbanana.ser"));
ObjectInputStream objin= new ObjectInputStream(fin);
b=(Banana2)objin.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println(" restored "+ b.size + "" );
}
}
Because that's how (de)serialization works. It is a separate mechanism from regular object construction.
If the constructor of Class A is called, that's because Class A itself does not implement Serializable
. During Deserialization, the parameterless constructor of the first non-serializable class in the inheritance hierarchy is called (possibly that of java.lang.Object
). If that class does not have a parameterless constructor, there will be an Exception.
Neither is called, because your class is not Serializable.
You cannot call the B()
without calling A()
because B calls A.
Consider the following program
public static void main(String... args) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(new B());
oos.writeObject(new D());
oos.close();
System.out.println("-------------");
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
System.out.println("deserialize B");
ois.readObject();
System.out.println("deserialize D");
ois.readObject();
}
static class A {
public A() {
System.out.println("Inside class A");
}
}
static class B extends A implements Serializable {
public B() {
System.out.println("Inside class B");
}
}
static class C implements Serializable {
public C() {
System.out.println("Inside class C");
}
}
static class D extends C {
public D() {
System.out.println("Inside class D");
}
}
prints
Inside class A
Inside class B
Inside class C
Inside class D
-------------
deserialize B
Inside class A
deserialize D
A is the non Serializable parent of B. It is not Serialized and so the constructor has to be called to set any fields which need to be set. However, B, C and D are all Serializable and their fields have been serializable and will be reset. There is no need to call the constructor.
If at all you want to re-create some information when the object is being deserialized, you should use the below method implementation inside your Serializable
class. For instance, put the below code inside B
.
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
System.out.println("Resurrecting B");
}
The other one is for serialization, just in case you want to do some stuff before the object gets written off.
private void writeObject(ObjectOutputStream out) throws IOException {
// do stuff.
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.