public class StaticVariableTest {
private static StaticVariableTest svt = new StaticVariableTest();//語句(1)
private static int count1;//語句(2)
private static int count2 = 0;//語句(3)
private StaticVariableTest(){//語句(4)
count1++;
count2++;
}
public static StaticVariableTest getInstance(){//語句(5)
return svt;
}
public static int getCount1() {
return count1;
}
public static void setCount1(int count1) {
StaticVariableTest.count1 = count1;
}
public static int getCount2() {
return count2;
}
public static void setCount2(int count2) {
StaticVariableTest.count2 = count2;
}
public static void main(String[] args) {
StaticVariableTest svt = StaticVariableTest.getInstance();//語句(6)
System.out.println("count1:" + svt.getCount1());//語句(7)
System.out.println("count1:" + svt.getCount2());//語句(8)
}
}
問題:當執行完語句(7)(8)時,打印結果分別是什么?為什么?
解答:當執行完語句(7)時,打印結果是1,當執行完語句(8)時,打印結果是0。分析:程序執行從main方法開始,首先執行語句(6),調用
getInstance方法,然而當它去調用這個方法的時候,它是一個靜態的方法,在這個類里面定義了多個靜態的成員變量。根據java初始化的順序我們
知道,對于靜態的內容肯定是先執行的,也就是說在執行getInstance方法之前,肯定先執行private static
StaticVariableTest svt = new
StaticVariableTest();而且它是從上到下分別執行靜態的內容。換句話說,這個程序首先執行private static
StaticVariableTest svt = new
StaticVariableTest();而這里面又要調用一個構造方法StaticVariableTest(),則去執行這個構造方法
private
StaticVariableTest(),執行這個構造方法時發現它里面的功能是將count1加1,將count2加1,而這個count1和
count2是我們定義的int類型的靜態變量。根據java對成員變量的默認值,count1和count2初始化的時候都被設置為0,當執行完構造方
法后count1和
count2都等于1,這時StaticVariableTest這個對象就生成了,已經在內存里面存在了。接著賦給svt這個引用。那么svt這個引用
指向的StaticVariableTest類型的對象,它里面的count1是1,count2也是1。接著發現下面一行private
static int
count1;它是一個靜態的,那么它要執行這行代碼,這行代碼只是一個聲明,但是沒有賦值,接著它就跳過這行不再賦值了(究其原因是因為count1已
經被賦值了,已經被加1了,也就是count1為1)。當我執行private static int count2 =
0;時發現count2也是一個靜態變量,而且有一個顯示的去賦值的這樣一個動作。我們知道count2已經被賦值1了,但是這兒有一個顯示的賦值的動
作,就把count2的值由1改變成了0。這個就是調用getInstance方法時程序的執行流程:語句(6)、語句(5)、語句(1)、語句(4)、
語句(2)、語句(3)
思考:如果將語句(2)和語句(3)放在語句(1)前面,當執行完語句(7)時,打印結果是1,當執行完語句(8)時,打印結果是1,想想是為什么?
總結:靜態變量的執行順序是按照它們定義在類里面的先后順序,按照從上到下來執行的。