java虛擬機器規定必須立即初始化類的5種情況
Java類載入機制中,規定了有且僅有5種情況必須立即對類進行初始化(而載入,驗證,準備自然再次之前):
1. 遇到new,getstatic,putstatic和invokestatic這4條指令時,如果類沒有初始化時,必須初始化類。四條指令對應我們日常所見的 使用new關鍵字例項化物件,讀取一個類的靜態欄位,設定一個類的靜態欄位(被final修飾的靜態欄位除外,因為已在編譯期把結果放入常量池中了)和呼叫一個類的靜態方法。
2. 對類進行反射呼叫時。
3. 當初始化一個子類時,發現其父類沒有初始化,則需先出發其父類的初始化。
4. 當虛擬機器啟動時,一個類包含main()方法時,當前類需要初始化
5. 但是用動態語言支援時,如果一個java.lang.invoke.MethodHandle例項後解析結果REF_putStatic,REF_getStatic,REF_invokeStatic的方法控制程式碼時,當改方法控制程式碼對應的類沒有初始化時,需要初始化該類。(動態語言支援詳情請檢視)
初次之外所有引用類的地方都不會出發類初始化,被稱為被動應用,下面舉三個例子:
1. 通過子類應用父類靜態欄位,不會導致子類初始化,程式碼如下:
package com.sun.jojo.noinitclass;
public class SuperClass {
static {
System.out.println("SuperClass Init !!!");
}
public static int value = 123;
}
package com.sun.jojo.noinitclass;
public class SubClass extends SuperClass{
static {
System.out.println("SubClass Init !!!");
}
}
package com.sun.jojo.noinitclass;
public class NotInitialization {
public static void main(String[] args) {
System.out.println(SubClass.value);
}
}
結果:
SuperClass Init !!!
123
結果只輸出了”SuperClass Init !!!”, “SubClass Init !!!”沒有出來,對應靜態欄位,只有直接定義改欄位的類才會初始化。
2 .通過陣列定義來引用類,不會出發此類的初始化,程式碼如下:
package com.sun.jojo.noinitclass;
public class NotInitialization {
public static void main(String[] args) {
//System.out.println(SubClass.value);
SuperClass[] superClasses = new SuperClass[10];
}
}
執行結果並沒有列印出”SuperClass Init !!!”,這裡並沒有出發com.sun.jojo.noinitclass.SuperClass類的初始化.這裡觸發了另一個名為“[Lcom.sun.jojo.noinitclass.SuperClass”的類的初始化,他是虛擬機器自動建立的,直接繼承於java.lang.Object的子類,建立動作由位元組碼指令newarray觸發。
3.常量在編譯期間就會調入類的常量池中,本質上沒有直接引用的定義變數的類,因此使用常量欄位時不會觸發累的初始化。
public class ConstClass {
static {
System.out.println("ConstClass Init !!!");
}
public static final int value = 123;
}
public class NotInitialization {
public static void main(String[] args) {
//System.out.println(SubClass.value);
//SuperClass[] superClasses = new SuperClass[10];
System.out.println(ConstClass.value);
}
}
結果:只列印出123 “ConstClass Init !!!”並沒有列印出來。
介面的初始化和類的初始化類似,區別在於5種中的第三種:當一個子類的初始化過程中需要去報其父類也必須先初始化,但介面初始化時不要求其父介面也進行初始化,只有在用到父介面時,才去初始化。
相關文章
- 【Java虛擬機器規範】JVM類載入機制Java虛擬機JVM
- java虛擬機器規範-載入、連結與初始化Java虛擬機
- java虛擬機器類載入機制Java虛擬機
- Java 虛擬機器類載入機制Java虛擬機
- Java類什麼情況下被初始化?Java
- Java JVM——5.Java虛擬機器棧JavaJVM虛擬機
- Dalvik虛擬機器、Java虛擬機器與ART虛擬機器虛擬機Java
- java虛擬機器和Dalvik虛擬機器Java虛擬機
- Android 虛擬機器 Vs Java 虛擬機器Android虛擬機Java
- Java虛擬機器(六):類載入機制Java虛擬機
- Java虛擬機器——類檔案結構Java虛擬機
- Java 虛擬機器之四:Java類載入機制Java虛擬機
- 大廠必問的Java虛擬機器面試題Java虛擬機面試題
- Debian、kali類虛擬機器網路設定虛擬機
- 作為程式設計師必須掌握的Java虛擬機器中的22個重難點程式設計師Java虛擬機
- JVM(三)-java虛擬機器類載入機制JVMJava虛擬機
- Java 虛擬機器之三:Java虛擬機器的記憶體結構Java虛擬機記憶體
- 深入理解Java虛擬機器 - 類載入機制Java虛擬機
- 深入理解Java虛擬機器(類載入機制)Java虛擬機
- 深入理解Java虛擬機器 --- 類載入機制Java虛擬機
- Java虛擬機器(JVM)Java虛擬機JVM
- java~graalVM虛擬機器JavaLVM虛擬機
- 深入java虛擬機器學習–類的載入機制(四)Java虛擬機機器學習
- 深入理解虛擬機器之虛擬機器類載入機制虛擬機
- Java虛擬機器,類檔案結構深度解析Java虛擬機
- Java虛擬機器之Class類檔案結構Java虛擬機
- Java虛擬機器的記憶體空間有幾種Java虛擬機記憶體
- Java虛擬機器的記憶體空間有幾種!Java虛擬機記憶體
- (深入理解 Java虛擬機器)一篇文章帶你深入瞭解Java 虛擬機器類載入器Java虛擬機
- 虛擬機器類載入機制虛擬機
- Java虛擬機器16:MetaspaceJava虛擬機
- 備戰- Java虛擬機器Java虛擬機
- 《深入理解java虛擬機器》第七章讀書筆記——虛擬機器類載入機制Java虛擬機筆記
- 深入學習Java虛擬機器——類檔案結構Java虛擬機
- 深入理解Java虛擬機器(類檔案結構)Java虛擬機
- 深入理解Java虛擬機器 – 類檔案結構Java虛擬機
- 出現VMware虛擬機器磁碟丟失的情況,使用這種解決方式實在是太有必要了虛擬機
- linux虛擬機器執行機必安裝Linux虛擬機
- 虛擬機器網路設定虛擬機