简体   繁体   中英

When I run the given code I get A B A as output. I don't understand why it prints A again

Tha code mentioned below returns ABA as output but I didnt understand the logic why A has been printed again after B.

class A1 {
    public A1() {
        System.out.println("A");
    }
}

class B extends A1 implements Serializable {
    public B() {
        System.out.println("B");
    }

}

public class Test {

    public static void main(String... args) throws Exception {
        B b = new B();      // Object of class B
        ObjectOutputStream objout=new ObjectOutputStream(new FileOutputStream("t.txt"));
        objout.writeObject(b);

        ObjectInputStream objin=new ObjectInputStream(new FileInputStream("t.txt"));
        objin.readObject();
    }

}

This explains it, the ctor of B is not called again because it's serializable.

Reading an object is analogous to running the constructors of a new object. Memory is allocated for the object and initialized to zero (NULL). No-arg constructors are invoked for the non-serializable classes.

AB is printed when you call new B() , which first calls the ctor of A and then B. Then objin.readObject() calls only the ctor of A and prints the second A .

When you extend any class, it will invoke constructor of super class while creating object of subclass .

Just example: object B created then it will first invoke constructor of A1 first. and objin.readObject() calls only constructor of A.

Edit:

The no-arg contructor of every non-serializable superclass will run when an object is deserialized. However, the deserialized objects? constructor does not run when it is deserialized.

The constructor for A is called during deserialization because A does not implement Serializable . This answer explains it well:

Java: Why doesn't deserialization invoke constructor & what's the best workaround?

Constructors are invoked from base class to derived classes..

So,for B b = new B(); Constructors would be invoked in the order A->B Hence printing AB


Now for objin.readObject();

Only A's constructor would be invoked not B's constructor.This is because

  • For serializable objects, the no-arg constructor for the first non-serializable supertype (ie A1 ) is run. Since A1 , doesn't implement Serializable,it's construtor would be invoked

  • Constructors are not executed for serializable classes(ie B ) during deserialization. Hence B's constructor is not invoked the second time

Hence the output, ABA

This is mentioned in doc

Java docs of ObjectInputStream says ,

Reading an object is analogous to running the constructors of a new object. Memory is allocated for the object and initialized to zero (NULL). No-arg constructors are invoked for the non-serializable classes and then the fields of the serializable classes are restored from the stream starting with the serializable class closest to java.lang.object and finishing with the object's most specific class.

Therefore while creating class B instance,

B b = new B();  // prints A B

it prints A ,B and

while deserializing ,

objin.readObject();  // prints A as per docs

it prints A because class A is non-serializable and docs says No-arg constructors are invoked for the non-serializable classes .

So together you get output as ABA

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM