jvm-008(張龍老師jvm教程) 初始化加載順序代碼示例分析

jvm-008

一、初始化的執行順序:類的初始化順序是按照代碼邏輯自上而下依次執行的。

代碼1:

public class TestCode06 {
	public static void main(String[] args) {
	    MyParent06 instance = MyParent06.getInstance();
		System.out.println("a : " + instance.a);//1
		System.out.println("b : " + instance.b);//0
	}
}

class MyParent06 {
	public static int a;
	public static int b = 0;
	public static MyParent06 mp = new MyParent06();
	
	public MyParent06() {
		a ++ ;
		b ++ ;
	}
	
	public static MyParent06 getInstance() {
		return mp;
	}
}

運行結果:

a : 1 
b : 1

分析:首先進行類的加載、連接、初始化,在連接的準備階段,對類的靜態變量賦予零值,準備階段過後,a = 0, b = 0, mp = null。在main方法中,MyParent06 instance = MyParent06.getInstance()代碼執行的時候,會執行 MyParent06 類中 mp = new MyParent06(),會引發 MyParent06 類的初始化。初始化順序分別是 a 不賦值, b = 0,mp = new MyParent06()會執行,在執行這一步的時候,會調用 MyParent06 類的實例代碼塊 {

        a ++ ;

        b ++ ;

}, 執行過後,a 和 b的值分別爲 a = 1, b = 1,所以在main方法中, 在獲取 instance.a / instance.b的數值的時候,結果都是1。

 

============================分割符==============================

 

代碼2:

public class TestCode06 {
	public static void main(String[] args) {
	    MyParent06 instance = MyParent06.getInstance();
		System.out.println("a : " + instance.a);//1
		System.out.println("b : " + instance.b);//0
	}
}

class MyParent06 {
	public static int a;
	public static MyParent06 mp = new MyParent06();
	public static int b = 0;
	
	public MyParent06() {
		a ++ ;
		b ++ ;
	}
	public static MyParent06 getInstance() {
		return mp;
	}
}

運行結果:

a : 1 
b : 0

分析:代碼2與代碼1的唯一區別就是

public static MyParent06 mp = new MyParent06() 和 public static int b = 0的順序發生了變化,但是結果就不一樣了。

同代碼的原理:MyParent06 類首先被加載,加載過後的 a = 0, b = 0, mp = null;之後再main方法中執行 MyParent06 instance = MyParent06.getInstance() 會觸發 MyParent06 類的初始化,初始化順序與代碼1有所不同:

首先 a 不賦值,仍舊是0,然後 是 mp = new MyParent06();此時創建對象會調用 MyParent06 類的實例代碼塊 {

       a ++ ;

        b ++ ;

},執行過後, a = 1, b = 1。再後面執行 int b = 0 的賦值過程,b又變爲0。所以在main方法中,打印結果 instance.a = 1, instance.b = 0;

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