搜尋

首頁  >  問答  >  主體

java类加载机制-类定义中new如何理解

高洛峰高洛峰2803 天前894

全部回覆(5)我來回復

  • 黄舟

    黄舟2017-04-18 10:48:41

    在執行 java 程式的時候,每個類別只載入一次。不可能重複加載的。所以也就不存在題主說的遞歸了。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-18 10:48:41

    推薦先了解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初始化理解

    回覆
    0
  • PHPz

    PHPz2017-04-18 10:48:41

    是不是把類別載入和物件初始化搞混了?

    回覆
    0
  • 怪我咯

    怪我咯2017-04-18 10:48:41

    樓主是不是想的太高深了?實例化和聲明定義是2個概念和階段。
    A2有幾個靜態的成員變數在宣告時實例化,而類別的實例化過程是透過建構子完成的。
    這裡看起來出現了嵌套,其實不然。編譯器可以在編譯實例化語句的時候申明指令跳轉,跳轉位址在二次編譯的時候決定。
    這樣,類別申明階段,在實例化a,b,c,d的時候編譯程式會跳到A2(int i)的建構方法程式區塊。
    在類別實例化階段的時候跳到A()建構方法。
    說白了就是在不同階段呼叫對應的構造方法而已,沒有樓主以為的循環嵌套。

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:48:41

    類別載入時,對於靜態變數和建構方法的載入順序不一樣。建構方法本質也是靜態方法。
    也不怎麼懂,先佔個板凳

    回覆
    0
  • 取消回覆