簡體   English   中英

Java:對象的初始化序列

[英]Java: initialization sequence of object

有一個代碼作為初級Java開發人員的任務給出。 我在五年內使用Java,這段代碼讓我很困惑:

public class Main {

    String variable;

    public static void main(String[] args) {
        System.out.println("Hello World!");
        B b = new B();
    }

    public Main(){
        printVariable();
    }

    protected void printVariable(){
        variable = "variable is initialized in Main Class";
    }
}

public class B extends Main {

    String variable = null;

    public B(){
        System.out.println("variable value = " + variable);
    }

    protected void printVariable(){
        variable = "variable is initialized in B Class";
    }
}

輸出將是:

Hello World!
variable value = null

但是如果我們改變String variable = null; String variable; 我們將有:

Hello World!
variable value = variable is initialized in B Class

第二個輸出對我來說更清楚。 所以,據我所知,Java中的inizialisation序列如下:

  • 當我們來到這個根父類時,我們轉到類層次結構的根(對於Java,它總是Object類):
    • 所有靜態數據字段都已初始化;
    • 執行所有靜態字段初始化程序和靜態初始化程序段;
    • 初始化所有非靜態數據字段;
    • 執行所有非靜態字段初始化器和非靜態初始化塊;
    • 執行默認構造函數;
  • 然后我們重復底層子類的過程。

還有post描述了this關鍵字在超類的上下文中的行為 - 從基類方法調用基類重寫函數

根據上面給出的規則,我假設有這樣的序列:

  1. 我們將創建一個B類的新實例;
  2. 我們去零件類Main ;
  3. 用null初始化main.variable ;
  4. 然后我們轉到Main類的默認構造函數;
  5. 構造函數在Main類中調用方法b.printVariable() ; (為什么不調用main.printvariable ?我們這里沒有this關鍵詞。)
  6. 字段b.variable變量在B類中初始化
  7. 現在我們回到B級;
  8. 我們應該用空值初始化字段b.variable ,我是對的嗎?
  9. 執行了B類的默認構造函數

請,有人可以完整和完整地解釋這種繼承i​​nizialisation序列是如何工作的。 為什么更改String variable = null; String variable; 導致另一個輸出。

順序是:

  1. 主要 - >“你好”
  2. 主要 - >新B()
  3. B() - > Main() - > b.printVariable() - >設置變量
  4. 回到初始化B,所以變量= null。

所以基本上,超級對象Main()是在B類的任何初始化事件之前構造的。這意味着變量= null會在以后發生。 這是有道理的,否則B可以打破Main的初始化。

約書亞布洛赫在他有效的java書中介紹了很多關於如何做正確的危險繼承的好理由,我會推薦它。

首先,您需要了解,當您編寫variable = null;時會發生什么variable = null; 該代碼何時執行。 這基本上決定了輸出。

在開始之前,我還應該提到,當您創建class B對象時,不會調用主類的printVariable()函數。 相反,總是會調用B的printVariable()

記住這一點,當你有variable = null ,B的構造函數的執行將開始。 將調用First Main() ,它將調用printVariable()方法。 最后, variable=null ,將被稱為覆蓋variable變量。

在另一種情況下,如果你沒有初始化variable=nullprintVariable()函數設置的variable將不會被覆蓋,因此你得到的是你所期望的。

總之,當你執行new B()時,這是語句的執行順序:

Main()     //super constructor
  B#printVariable()
  initializtion of variables in B's constructor (if any) [i.e. variable=null, if present]

這是一個很好的運動! 但要問初級開發人員,這不是一個公平的問題。 這個適合老年人。 但是為了使這個文本在技術訪談中有用,我通過在Main的構造函數中添加一個參數來修改它:

public Main(String something){
 printVariable();
}

如果該人將回答將要發生的事情,那么刪除該論點並詢問原始問題。 如果這個人不回答 - 沒有必要繼續 - 他/她是初中。

您還可以刪除B類中受保護的限定符,並詢問如果您的目標是不雇用此人將會發生什么:)

暫無
暫無

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

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