1. 程式人生 > >單例模式和類載入的實際案例分析(java)

單例模式和類載入的實際案例分析(java)

類載入的步驟包括載入、準備、驗證、解析、初始化、使用等過程,本文主要分析例項程式碼,一步步分析得出輸出結果。要分析的例項程式碼如下:

public class Singleton {
	private static Singleton instance = new Singleton(); 
	public static int counter1;
	public static int counter2 = 0;
	
	private Singleton() {
		counter1++;
		counter2++;
	}
	
	public static Singleton getInstance() {
		return instance;
	}
	
	public static void main(String[] args) {
		MyMain.main(args);
	}
}

class MyMain {
	public static void main(String[] args) {
		Singleton obj = Singleton.getInstance();
		System.out.println("counter1 == " + obj.counter1);
		System.out.println("counter2 == " + obj.counter2);
	}
}
程式碼在不執行的情況下能夠通過分析,得出結果麼?我們一步步分析一下。(程式碼中兩個類兩個main方法,只因為想在測試類MyMain裡對Singleton類進行測試,但是eclipse執行時找不到選項,才在Singleton類中main方法中呼叫了MyMain類的main方法。)

在程式啟動時,程式會尋找包含main方法的類,這裡我指定Singleton類中的main方法作為首先啟動項,Singleton類會被載入。在準備階段,instance靜態欄位會被賦值為null,counter1和counter2欄位會被賦值為0;在初始化階段,發現Singleton類含有靜態欄位,會為Singleton類生成clinit方法,該方法包含了所有靜態欄位的賦值操作,且順序為靜態欄位宣告的順序。所以,初始化一開始,instance會使用new關鍵字新建一個Singleton物件。使用new關鍵字是,Singleton類的私有構造器會被呼叫,所以counter1 = 1, counter2 = 1; clinit方法繼續執行,counter2因為有賦值操作,所以在clinit中它會被賦值counter2 = 0。

Singleton類的載入結束了,進入MyMain的main方法中,由於Singleton類已經被載入,所以直接返回instance物件,列印的值為:

counter1 = 1
counter2 = 0