單例模式中靜態變數初始化與不初始化有什麼區別
阿新 • • 發佈:2019-02-08
這個和Java初始化順序有關,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); } }
由於你的第一句是
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去掉會造成空間方面的浪費。