在網上看了一個這樣的題目java
public class StaticTest { public static void main(String[] args) { staticFunction(); } static StaticTest st = new StaticTest(); static { System.out.println("1"); } { System.out.println("2"); } StaticTest() { System.out.println("3"); System.out.println("a=" + a + ",b=" + b); } public static void staticFunction() { System.out.println("4"); } int a = 110; static int b = 112; }
問輸出順序是什麼?函數
正確答案是:spa
2
3
a=110,b=0
1
4
產生這個結果的緣由的關鍵在這一句話:
static StaticTest st = new StaticTest();
st變量的引用是本類的實例,所以在實例化st變量時,將實例初始化嵌入到靜態初始化中。由於這一句放在靜態初始化的開頭,因此static int b=112沒有被調用,輸出的b=0,同時,輸出1也在2和3後面。在對象的初始化時,也是先初始化環境變量,再執行構造函數,a的值爲100。code
後面我在想把static int b = 112放到st以前會發生什麼對象
public class StaticTest { public static void main(String[] args) { staticFunction(); } static int b = 112; static StaticTest st = new StaticTest(); static { System.out.println("1"); } { System.out.println("2"); } StaticTest() { System.out.println("3"); System.out.println("a=" + a + ",b=" + b); } public static void staticFunction() { System.out.println("4"); } int a = 110; }
執行結果:blog
2
3
a=110,b=112
1
4
b有值了。因此b在st聲明前賦值,st實例化的時候b就有值了。說明靜態變量之間實例化是按代碼順序執行的。io
若是把靜態代碼塊,提到st以前會發生什麼呢?class
public class StaticTest { public static void main(String[] args) { staticFunction(); } static { System.out.println("1"); } static StaticTest st = new StaticTest(); { System.out.println("2"); } StaticTest() { System.out.println("3"); System.out.println("a=" + a + ",b=" + b); } public static void staticFunction() { System.out.println("4"); } int a = 110; static int b = 112; }
執行結果:變量
1
2
3
a=110,b=0
4
發現執行順序變了,它會先執行靜態代碼塊,再執行st的實體化。構造函數
這邊,我發現靜態代碼塊與靜態成員變量的初始化竟然和代碼順序有關
因此無論是靜態代碼塊仍是靜態成員變量,java都是哪一個在前面先執行哪一個。