簡體   English   中英

“ new”關鍵字和構造函數的工作原理

[英]How exactly does the 'new' keyword and constructors work

好的,所以我正在研究我的第一個Java認證,而且我還不太了解在創建對象時引擎蓋下到底發生了什么,一些讀過的解釋指出,構造函數將引用返回給對象,即這讓我感到困惑,因為根據我的理解,這是由new關鍵字完成的。 我的問題是:

  1. 對對象的引用實際上來自“ new”關鍵字還是構造函數?
  2. 使用'new'關鍵字創建對象時,是否將其隱式傳遞給構造函數?
  3. 當使用'new'關鍵字創建對象時,它只是一個Java對象,直到將其傳遞給構造函數為止。 人我= new Person(); 該對象是在創建后立即與類person關聯的,還是僅在將其傳遞給構造函數之后才與它關聯的對象
  1. new Constructor(arguments)的整個表達式被視為一個實例創建表達式,作為單獨的new關鍵字和構造函數調用沒有意義。

    JLS 15.9.4描述了實例的實際創建,包括三個步驟:

    1. 限定表達式(使用new時不適用)
    2. 在內存中為實例分配空間,並將字段設置為默認值。
    3. 評估構造函數的參數,然后調用構造函數。

    首先,如果類實例創建表達式是合格的類實例創建表達式,則對合格的主表達式進行求值。 如果限定表達式的結果為null,則引發NullPointerException,並且類實例創建表達式突然完成。 如果限定表達式突然完成,則類實例創建表達式由於相同的原因突然完成。

    接下來,為新的類實例分配空間。 如果沒有足夠的空間來分配對象,則通過拋出OutOfMemoryError突然完成對類實例創建表達式的評估。

    新對象包含在指定類類型及其所有超類中聲明的所有字段的新實例。 創建每個新的字段實例時,會將其初始化為其默認值(第4.12.5節)。

    接下來,從左到右評估構造函數的實際參數。 如果任何一個參數求值突然完成,則不會評估其右邊的任何參數表達式,並且出於相同的原因,類實例創建表達式也會突然完成。

    接下來,將調用指定類類型的選定構造函數。 這導致為類類型的每個超類調用至少一個構造函數。 此過程可以由顯式構造函數調用語句(第8.8節)指導,並在第12.5節中詳細指定。

    類實例創建表達式的值是對指定類的新創建對象的引用。 每次對表達式求值時,都會創建一個新對象。

  2. 是的,因為字節碼全部變為一個invokespecial調用,新實例位於傳遞的參數堆棧的底部。 請參閱此答案的底部。 語義,但是,構造並沒有得到新的實例“傳遞”給它,但該實例提供的this Java源代碼。

  3. 這個問題在語義上沒有意義,因為在構造函數返回之前,對象不會“存在”於外界。 如果構造突然終止,則該對象實際上不會創建並且不可用。 但是 ,至少在OpenJDK JVM的內存中,對象的類型以及它擴展/實現的任何類型都將寫入內存標頭中。 但是,並非所有實現都可以保證。

拆卸:

我編譯並反匯編:

class Test{
    public static void main(String args[]){
        Integer s = new Integer(2);
    }
}

結果如下:

public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/lang/Integer
       3: dup
       4: iconst_2
       5: invokespecial #3                  // Method java/lang/Integer."<init>":(I)V
       8: astore_1
       9: return

如您所見,首先使用new分配對象,該對象將默認填寫所有字段。 它是重復的,因此堆棧如下所示:

our new Integer
our new Integer

然后將我傳遞給構造函數的常量值壓入:

2
our new Integer
our new Integer

發生invokespecial ,它傳遞頂部的兩個堆棧元素-新實例和構造函數的參數。

暫無
暫無

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

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