Java子父類間靜態程式碼塊、構造程式碼塊、構造方法的執行順序
阿新 • • 發佈:2019-02-18
在學習Java基礎期間,子父類的靜態程式碼塊、構造程式碼塊、構造方法的執行順序容易混淆,現在通過一段程式來說明它們的執行順序。
一、先看一個簡單的靜態測試程式:
執行子類的靜態程式碼塊。
執行父類的構造程式碼塊。
執行父類的不帶引數的構造方法。
執行子類的構造程式碼塊。
執行子類的不帶引數的構造方法。
執行結果: 執行父類的靜態程式碼塊。
執行子類的靜態程式碼塊。
執行父類的構造程式碼塊。3
執行父類的構造程式碼塊。3
執行父類的構造程式碼塊。7
執行父類的帶引數的構造方法。
執行子類的構造程式碼塊。3
執行子類的構造程式碼塊。3
執行子類的構造程式碼塊。7
執行子類的帶引數的構造方法。
二、結論: 1、執行順序:父類的靜態程式碼塊--->子類的靜態程式碼塊--->父類的構造程式碼塊--->父類的構造方法--->子類的構造程式碼塊--->子類的構造方法。 2、靜態程式碼塊隨類的載入而執行,只執行一次,優先於main方法,用於初始化整個類。 3 、構造程式碼塊是給一個類的所有的物件進行初始化,可執行多次。只要物件一建立,就會呼叫構造程式碼塊。構造程式碼塊可以重複,可以有多份。
4、構造方法是給與之對應的物件進行初始化,有針對性。構造方法要麼帶引數,要麼不帶引數。當類中沒有顯式的構造方法時,jvm會預設執行一個不帶引數的構造方法。同一個類中不能出現兩個或兩個以上相同的構造方法(方法名和引數列表都相同)。
5、在子類的所有構造方法中如果沒有顯式的super語句,則預設第一條語句為隱式的super語句:super();會訪問父類的不帶引數的構造方法。當父類中只有帶引數的構造方法時,子類必須用顯式的帶引數的super語句訪問父類的構造方法。若顯示的super語句不帶引數,則編譯失敗。當父類中只有顯式的不帶引數的構造方法時,子類必須用顯示的不帶引數的super語句訪問父類的構造方法。否則,編譯失敗。
6、在建立子類的例項物件時未傳入引數,若子類只有帶引數的構造方法則編譯失敗。若子類有不帶引數的構造方法,則執行子類的不帶引數的構造方法。若子類沒有構造方法,則執行隱式的不帶引數的構造方法。
7、在建立子類的例項物件時傳入引數:若子類有帶引數的構造方法,則執行子類的帶引數的構造方法;若子類沒有帶引數的構造方法或者沒有構造方法,則編譯失敗。
執行結果: 執行父類的靜態程式碼塊。class FatherStaticTest { static//靜態程式碼塊 { System.out.println("執行父類的靜態程式碼塊。"); } FatherStaticTest()//父類不帶引數的構造方法 { System.out.println("執行父類的不帶引數的構造方法。"); } FatherStaticTest(int num)//父類帶引數的構造方法 { System.out.println("執行父類的帶引數的構造方法。"); } //構造程式碼塊 { System.out.println("執行父類的構造程式碼塊。"); } } class SonStaticTest extends FatherStaticTest { static { System.out.println("執行子類的靜態程式碼塊。"); } SonStaticTest() { System.out.println("執行子類的不帶引數的構造方法。"); } SonStaticTest(int num) { System.out.println("執行子類的帶引數的構造方法。"); } { System.out.println("執行子類的構造程式碼塊。"); } } class StaticTest { public static void main(String[] args) { new SonStaticTest(); } }
執行子類的靜態程式碼塊。
執行父類的構造程式碼塊。
執行父類的不帶引數的構造方法。
執行子類的構造程式碼塊。
執行子類的不帶引數的構造方法。
class FatherStaticTest { static { System.out.println("執行父類的靜態程式碼塊。"); } FatherStaticTest() { System.out.println("執行父類的不帶引數的構造方法。"); } FatherStaticTest(int num) { System.out.println("執行父類的帶引數的構造方法。"); } FatherStaticTest(String str) { System.out.println("執行父類的帶引數的構造方法。"); } { int i = 1; int j = 2; int sum = (i+j); System.out.println("執行父類的構造程式碼塊。"+sum); } { int i = 1; int j = 2; int sum = (i+j); System.out.println("執行父類的構造程式碼塊。"+sum); } { int m = 3; int n = 4; int sum = (m+n); System.out.println("執行父類的構造程式碼塊。"+sum); } } class SonStaticTest extends FatherStaticTest { static { System.out.println("執行子類的靜態程式碼塊。"); } SonStaticTest() { System.out.println("執行子類的不帶引數的構造方法。"); } SonStaticTest(int num) { super(7); System.out.println("執行子類的帶引數的構造方法。"); } SonStaticTest(String str) { super(7); System.out.println("執行子類的帶引數的構造方法。"); } { int i = 1; int j = 2; int sum = (i+j); System.out.println("執行子類的構造程式碼塊。"+sum); } { int i = 1; int j = 2; int sum = (i+j); System.out.println("執行子類的構造程式碼塊。"+sum); } { int m = 3; int n = 4; int sum = (m+n); System.out.println("執行子類的構造程式碼塊。"+sum); } } class StaticTest { public static void main(String[] args) { new SonStaticTest("a"); } }
執行結果: 執行父類的靜態程式碼塊。
執行子類的靜態程式碼塊。
執行父類的構造程式碼塊。3
執行父類的構造程式碼塊。3
執行父類的構造程式碼塊。7
執行父類的帶引數的構造方法。
執行子類的構造程式碼塊。3
執行子類的構造程式碼塊。3
執行子類的構造程式碼塊。7
執行子類的帶引數的構造方法。
二、結論: 1、執行順序:父類的靜態程式碼塊--->子類的靜態程式碼塊--->父類的構造程式碼塊--->父類的構造方法--->子類的構造程式碼塊--->子類的構造方法。 2、靜態程式碼塊隨類的載入而執行,只執行一次,優先於main方法,用於初始化整個類。 3