簡體   English   中英

當我運行給定代碼時,我得到A B A作為輸出。我不明白為什么它再次打印A.

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

下面提到的Tha代碼返回ABA作為輸出但我不理解為什么A在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();
    }

}

這解釋了它,B的ctor沒有被再次調用,因為它是可序列化的。

讀取對象類似於運行新對象的構造函數。 為對象分配內存並初始化為零(NULL)。 對非可序列化類調用No-arg構造函數。

當你調用new B()時會打印AB ,它首先調用A的ctor然后調用B.然后objin.readObject()只調用A的ctor並打印第二個A

當你擴展任何類時,它將在創建subclass對象時調用super class構造函數。

只是示例: object B創建然后它將首先調用A1的構造函數。 objin.readObject()只調用A的構造函數。

編輯:

每個不可序列化的超類的no-arg構造函數將在反序列化對象時運行。 但是,反序列化的對象? 構造函數在反序列化時不會運行。

在反Serializable期間調用A的構造函數,因為A不實現Serializable 這個答案解釋得很好:

Java:為什么反序列化不會調用構造函數以及什么是最佳解決方法?

構造函數從基類調用到派生類。

所以,對於B b = new B(); 將按照A-> B的順序調用構造函數,從而打印AB


現在為objin.readObject();

只調用A的構造函數而不是B的構造函數。這是因為

  • 對於可序列化對象,運行第一個非可序列化超類型(即A1 )的no-arg構造函數。 由於A1 ,沒有實現Serializable,它的construtor將被調用

  • 在反serializable期間, 為可serializable類(即B )執行構造函數。 因此第二次不調用B的構造函數

因此輸出, ABA

這在doc中提到

ObjectInputStream的 Java文檔說,

讀取對象類似於運行新對象的構造函數。 為對象分配內存並初始化為零(NULL)。 對非序列化類調用no-arg構造函數,然后從最接近java.lang.object的可序列化類開始從流中恢復可序列化類的字段,並以對象的最特定類結束。

因此在創建B類實例時,

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

它打印A,B和

反序列化時,

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

它打印A,因為類A是不可序列化的,並且docs表示為非可序列化類調用No-arg構造函數。

所以你一起輸出ABA

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM