AVA物件實例化過程中,主要使用到的包括虛擬機棧,JAVA堆和方法區。 JAVA檔案經過編譯之後首先會被加到JVM方法區,JVM方法區中很重要的一個部分是運行時常數池-用以儲存class檔案類別的版本、欄位、方法、介面等描述資訊和編譯期間的常數和靜態變數。 JAVA物件真正進行實例化的地方在JAVA堆和虛擬機棧中,Object A = New Object();在實際記憶體中,A其實相當於我們給Ojbect這個類別的實作起的一個名字,在物件導向在程式設計中,就像狗是屬於一類動物,但是特指的那一條狗我們會給他起一個名字用以區分一樣。 Object用以標記A是屬於這個類,而A是特指Object的一個具體實現,而New Object就相當於對這個類別創建一個具體實現。所以我們可以了解到,一個物件他首先必須可以指明所屬的類,其次它還必須能指明他所特指的哪一個具體實現。 對應的有兩種實作方式:
在執行 java 程式的時候,每個類別只載入一次。不可能重複加載的。所以也就不存在題主說的遞歸了。
推薦先了解JVM虛擬機器中記憶體
AVA物件實例化過程中,主要使用到的包括虛擬機棧,JAVA堆和方法區。
JAVA檔案經過編譯之後首先會被加到JVM方法區,JVM方法區中很重要的一個部分是運行時常數池-用以儲存class檔案類別的版本、欄位、方法、介面等描述資訊和編譯期間的常數和靜態變數。
JAVA物件真正進行實例化的地方在JAVA堆和虛擬機棧中,Object A = New Object();在實際記憶體中,A其實相當於我們給Ojbect這個類別的實作起的一個名字,在物件導向在程式設計中,就像狗是屬於一類動物,但是特指的那一條狗我們會給他起一個名字用以區分一樣。 Object用以標記A是屬於這個類,而A是特指Object的一個具體實現,而New Object就相當於對這個類別創建一個具體實現。所以我們可以了解到,一個物件他首先必須可以指明所屬的類,其次它還必須能指明他所特指的哪一個具體實現。
對應的有兩種實作方式:
1.句柄存取物件
2.直接指標存取物件
直接指標存取物件
HotSpot採用的是第二種實作方式。
Class的裝載包含3個步驟:載入(loading),連接(link),初始化(initialize)
載入
根據上圖所示,我們不難理解,當一個物件進行實例化的時候,JVM會根據所需物件類型在JAVA堆疊中劃分記憶體區,並產生指向方法區物件資料類型的指標用於識別物件。
連結
虛擬機棧中的本地變數表(也有稱為局部變數表)中指標指向JAVA堆中劃分好的記憶體區域。 JAVA虛擬機器採用動態連結方式,只有編譯後的class檔案並未儲存最終方法在記憶體的表現形式。
初始化
初始化實際上是對class檔案中的初始化方法進行調用,其核心還是虛擬機器堆疊中堆疊幀的一次POP/PUSH。相當於對類別中的物件進行一次同樣的裝載過程。
至此,一個物件完整的實例化過程就全部介紹完畢。
類內部初始化順序為 靜態域->非靜態域->建構方法
推薦看一下:
【JAVA筆記-道】物件生命週期詳解
【JAVA筆記-道】Class初始化理解
是不是把類別載入和物件初始化搞混了?
樓主是不是想的太高深了?實例化和聲明定義是2個概念和階段。
A2有幾個靜態的成員變數在宣告時實例化,而類別的實例化過程是透過建構子完成的。
這裡看起來出現了嵌套,其實不然。編譯器可以在編譯實例化語句的時候申明指令跳轉,跳轉位址在二次編譯的時候決定。
這樣,類別申明階段,在實例化a,b,c,d的時候編譯程式會跳到A2(int i)的建構方法程式區塊。
在類別實例化階段的時候跳到A()建構方法。
說白了就是在不同階段呼叫對應的構造方法而已,沒有樓主以為的循環嵌套。
類別載入時,對於靜態變數和建構方法的載入順序不一樣。建構方法本質也是靜態方法。
也不怎麼懂,先佔個板凳