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種中的第三種:當一個子類的初始化過程中需要去報其父類也必須先初始化,但介面初始化時不要求其父介面也進行初始化,只有在用到父介面時,才去初始化。
相關文章
- MySQL必須flush privileges的兩種情況MySql
- 【Java虛擬機器規範】JVM類載入機制Java虛擬機JVM
- java虛擬機器規範-載入、連結與初始化Java虛擬機
- Java虛擬機器 —— 類的載入機制Java虛擬機
- java虛擬機器類載入機制Java虛擬機
- Java 虛擬機器類載入機制Java虛擬機
- Java虛擬機器10:類載入器Java虛擬機
- Java類什麼情況下被初始化?Java
- Java JVM——5.Java虛擬機器棧JavaJVM虛擬機
- Java虛擬機器9:Java類載入機制Java虛擬機
- 大廠必問的Java虛擬機器面試題Java虛擬機面試題
- Dalvik虛擬機器、Java虛擬機器與ART虛擬機器虛擬機Java
- Java虛擬機器類載入的過程Java虛擬機
- Java虛擬機器(六):類載入機制Java虛擬機
- 你必須知道的幾種java容器(集合類)Java
- Java虛擬機器——類檔案結構Java虛擬機
- Java 虛擬機器之四:Java類載入機制Java虛擬機
- java虛擬機器和Dalvik虛擬機器Java虛擬機
- Android 虛擬機器 Vs Java 虛擬機器Android虛擬機Java
- 維護無線網路安全五種必須避免的情況(轉)
- 《深入理解java虛擬機器》學習筆記7——Java虛擬機器類生命週期Java虛擬機筆記
- JVM(三)-java虛擬機器類載入機制JVMJava虛擬機
- 作為程式設計師必須掌握的Java虛擬機器中的22個重難點程式設計師Java虛擬機
- 基類中定義的虛擬函式,子類中必須要覆蓋嗎?為什麼?函式
- 虛擬機器入門二,虛擬機器的三種網路模式虛擬機模式
- Java 虛擬機器之三:Java虛擬機器的記憶體結構Java虛擬機記憶體
- Debian、kali類虛擬機器網路設定虛擬機
- Java虛擬機器5:Java垃圾回收(GC)機制詳解Java虛擬機GC
- Java虛擬機器類裝載的原理及實現Java虛擬機
- 深入理解Java虛擬機器(類載入機制)Java虛擬機
- 深入理解Java虛擬機器 - 類載入機制Java虛擬機
- Java虛擬機器(JVM)Java虛擬機JVM
- Java虛擬機器(轉)Java虛擬機
- 深入理解虛擬機器之虛擬機器類載入機制虛擬機
- Java虛擬機器,類檔案結構深度解析Java虛擬機
- Java虛擬機器之Class類檔案結構Java虛擬機
- Java虛擬機器的組成Java虛擬機
- 虛擬機器類載入機制虛擬機