在Java筆試中,構造方法、實例初始化、靜態初始化執行順序,是一個經常被考察的知識點。
像下面的這道題(剛剛刷題做到,雖然做對了,但是還是想整理一下)
運行下面的代碼,輸出的結果是...
1 class A { 2 public A() { 3 System.out.println("class A"); 4 } 5 { System.out.println("I'm A class"); } 6 static { System.out.println("class A static"); } 7 } 8 public class B extends A { 9 public B() { 10 System.out.println("class B"); 11 } 12 { System.out.println("I'm B class"); } 13 static { System.out.println("class B static"); } 14 15 public static void main(String[] args) { 16 new B(); 17 } 18 }
如果你了解執行順序,這道題的答案就顯而易見了
1 class A static 2 class B static 3 I'm A class 4 class A 5 I'm B class 6 class B
我們現在來總結一下,這個順序是因為什么!
需要考慮的就是 java 中構造方法、實例初始化、靜態初始化執行順序
我們先拿單個的類來講,執行順序是 靜態初始化塊 -> 初始化塊 -> 構造器
我們知道,當子類繼承父類時,執行順序是先執行父類,再執行子類。根據上述的順序,我們可以得到如下的執行順序:
- 父類靜態初始化塊
- 子類靜態初始化塊
- 父類初始化塊
- 父類構造器
- 子類初始化塊
- 子類構造器
當我們實例化兩次 B的時候:
1 class A { 2 public A() { 3 System.out.println("class A"); 4 } 5 { System.out.println("I'm A class"); } 6 static { System.out.println("class A static"); } 7 } 8 public class B extends A { 9 public B() { 10 System.out.println("class B"); 11 } 12 { System.out.println("I'm B class"); } 13 static { System.out.println("class B static"); } 14 15 public static void main(String[] args) { 16 new B(); 17 new B(); 18 } 19 }
可以得到如下的輸出
1 class A static 2 class B static 3 I'm A class 4 class A 5 I'm B class 6 class B 7 I'm A class 8 class A 9 I'm B class 10 class B
可見,靜態初始化塊只會在類初次加載的時候執行,所以才得到如上的運行結果,而非靜態代碼塊和構造器則每 new 一次就執行一次.
static修飾的語句或變量的特點有:
1. 隨着類的加載而加載
2. 優先於對象存在
3. 為所有的對象共享
4. 可以使用類名調用,即類方法