1. 程式人生 > >單例模式中靜態變數初始化與不初始化有什麼區別

單例模式中靜態變數初始化與不初始化有什麼區別

public class Singleton { 
	private static Singleton obj = new Singleton(); 
	public static int counter1; 
	public static int counter2 = 0; 
	private Singleton(){ 
		counter1++; 
		counter2++; 
	} 

	public static Singleton getInstance(){ 
		return obj; 
	} 

	public static void main(String[] args) { 

		Singleton obj = Singleton.getInstance(); 
		System.out.println("obj.counter1: " + obj.counter1); 
		System.out.println("obj.counter2: " + obj.counter2); 
	} 

} 
這個和Java初始化順序有關, 
由於你的第一句是 
private static Singleton obj = new Singleton(); 
所以在初始化靜態變數obj時中間插入了一個建構函式,造成了counter1和counter2最後的結果不一樣。完整的時間鏈如下 

1) JVM呼叫Singleton.Main,由於這是一個static method,JVM必須構造Singleton的所有static member,按照Java Specifiction的要求,指標被初始化為null,數值為0。到此為止 counter1=0,counter2=0 

2)接下來,按照自上而下的順序,完成所有static member的賦值操作。第一個賦值操作是(static)obj = new Singleton() ,JVM會呼叫Singleton的建構函式,完成counter1和counter2的賦值。到此為止 counter1=1,counter2=1 


3)接著執行的是rivate static Singleton obj = new Singleton();的下一句(public static int)counter2 = 0;到此為止 counter1=1,counter2=0 


你可以試試把private static Singleton obj = new Singleton();放到最後,則結果就都是1了。 

另外說一句,你這個所謂單例的用法是不正確的。既然已經把Singleton設為單例,counter1和counter2也就沒有必要設為static,這樣由於static member會在non static member面前被初始化,自然就沒有這個問題了。同時由於Singleton被設為了單例,也不用擔心把counter1和counter2前面的static去掉會造成空間方面的浪費。