類的例項化順序和分析

weixin_34138377發表於2018-10-17

1. 父類靜態成員和靜態初始化塊 ,按在程式碼中出現的順序依次執行
2. 子類靜態成員和靜態初始化塊 ,按在程式碼中出現的順序依次執行
3. 父類例項成員和例項初始化塊 ,按在程式碼中出現的順序依次執行
4. 父類構造方法
5. 子類例項成員和例項初始化塊 ,按在程式碼中出現的順序依次執行
6. 子類構造方法
結論:物件初始化的順序,先靜態方法,再構造方法,每個又是先基類後子類。

物件例項化分析

對記憶體分配情況分析最常見的示例便是物件例項化:
Object obj = new Object();
這段程式碼的執行會涉及 Java 棧、Java 堆、方法區三個最重要的記憶體區域。假設該語句出現在方法體中,及時對 JVM 虛擬機器不瞭解的 Java 使用這,應該也知道 obj 會作為引用型別(reference)的資料儲存在 Java 棧的本地變數表中,而會在 Java 堆中儲存該引用的例項化物件,但可能並不知道,Java 堆中還必須包含能查詢到此物件型別資料的地址資訊(如物件型別、父類、實現的介面、方法等),這些型別資料則儲存在方法區中。
另外,由於 reference 型別在 Java 虛擬機器規範裡面只規定了一個指向物件的引用,並沒有定義這個引用應該通過哪種方式去定位,以及訪問到 Java 堆中的物件的具體位置,因此不同虛擬機器實現的物件訪問方式會有所不同,主流的訪問方式有兩種:使用控制程式碼池和直接使用指標。
通過控制程式碼池訪問的方式如下:


5501600-44ee03048974d952.png

通過直接指標訪問的方式如下:


5501600-7aeaa368d184ae55.png

這兩種物件的訪問方式各有優勢,使用控制程式碼訪問方式的最大好處就是 reference 中存放的是穩定的控制程式碼地址,在物件被移動(垃圾收集時移動物件是非常普遍的行為)時只會改變控制程式碼中的例項資料指標,而 reference 本身不需要修改。使用直接指標訪問方式的最大好處是速度快,它節省了一次指標定位的時間開銷。目前 Java 預設使用的 HotSpot 虛擬機器採用的便是是第二種方式進行物件訪問的。

相關文章