Java虛擬機類加載機制(一)——類加載的時機

虛擬機如何加載Class文件?
Class文件裏的信息進入虛擬機會發生怎樣的變化?

虛擬機把描述類的數據從class文件加載到內存,並對數據進行校驗、轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是類加載機制

類加載的時機

類從被加載到內存到卸載出內存,生命週期:
加載、連接(驗證、準備、解析)、初始化、使用、卸載
初始化

  1. 遇到new、getstatic、putstatic或invokestatic,若類未初始化,則觸發初始化
  2. 使用java.lang.reflect對類進行反射調用
  3. 父類沒有進行過初始化,先初始化父類
  4. 虛擬機啓動時,先初始化要執行的主類
  5. 若java.lang.invoke.MethodHandle實例最後的解析結果爲REF_getStatic、REF_putStatic、REF_invokeStatic的句柄,若此方法句柄對應的類沒有進行過初始化,則要先初始化。

下面以代碼來演示

//父類superClass
public class SuperClass {
	static {
		System.out.println("SuperClass init!");
	}
	public static int sup = 1111111;
}
//子類subClass
public class subClass extends SuperClass{
	static {
		System.out.println("SubClass init!");
	}
	public static int sub = 2222222;
}

在這裏插入圖片描述
guess結果是啥?

分析,參考上面規則的第三條: 3. 父類沒有進行過初始化,先初始化父類
首先是subClass.sub:要調用子類中的靜態變量sub,那就要初始化子類,但是在子類初始化之前,還要去先初始化父類,最後纔打印sub的值
在運行第二句時,兩個類已經經過初始化,那麼直接打印值即可。
在這裏插入圖片描述

public static void main(String[] args) {
		SuperClass[] sca = new SuperClass[10];;
	}

這樣,並沒有輸出superClass init!
它代表了元素類型爲superClass的一維數組,它是繼承於java.lang.Object的子類

public class ConstClass {
	static{
		System.out.println("ConstClass init!");
	}
	public static final String Hello = "Hello!";
}
public class NotInitialization {
	public static void main(String[] args) {
		System.out.println(ConstClass.Hello);
	}
}

輸出什麼?
Hello!在這裏插入圖片描述
爲啥沒有執行static裏面的語句呢???
這裏用了final,即Hello是常量,它被存放在常量池中,和ConstClass這個類沒有了聯繫,主函數在執行時,不需要對ConstClass類進行初始化,所以最終只打印“ Hello!”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章