下面通過一個例子來說明java類中不同代碼塊的執行順序.
class B {
//靜態變量
static int a = 0;
//非靜態代碼塊
{
System.out.println("B.scope is running");
a = 10 ;
}
//靜態代碼塊
static {
System.out.println("B.static scope is running");
a = 20;
}
//構造函數
public B() {
System.out.println("B.Constructor is running");
}
public static void main(String arg[]) {
System.out.println(B.a);
System.out.println(B.a);
B b1 = new B();
B b2 = new B();
System.out.println(b1.a);
System.out.println(b2.a);
System.out.println(B.a);
}
}
輸出結果如下:
B.static scope is running
20
20
B.scope is running
B.Constructor is running
B.scope is running
B.Constructor is running
10
10
10
由此我們得到,java中靜態代碼塊首先被執行,且只被執行一次,當實例化一個對象之後,將會首先執行非靜態代碼塊,接着執行構造函數。
當一個類從被JVM裝載開始,各種代碼的執行順序大致如下:
被JVM裝載->執行父類的相關代碼->如果有靜態初始化,先執行靜態初始化,且只執行一次,以後即使有該類實例化,也不會再執行->如果有靜態代碼塊,以與靜態初始化一樣的方式執行->如果有new語句帶來的實例化,先爲成員變量分配空間,並綁定參數列表,隱式或顯式執行super(),即父類的構造方法,->執行非靜態代碼塊-〉執行本類的構造函數-〉執行其他代碼