子類實例化時,必先執行父類建構子。若父類無無參建構子,子類必須顯式呼叫super(參數)且置於第一行。
class SuperClass {
SuperClass() { System.out.println("SuperClass constructor"); }
}
class SubClass extends SuperClass {
SubClass() { System.out.println("SubClass constructor"); }
}
// 輸出:SuperClass constructor → SubClass constructor
class SuperClass {
SuperClass(String s) { System.out.println("Super with string"); }
}
class SubClass extends SuperClass {
SubClass(String s) {
// super(s); // 必須顯式呼叫,否則編譯失敗
System.out.println("Sub with string");
}
}
兩種修正方案差異:
super(str) → 輸出"Super with string" → "Sub with string"建立物件時,執行順序嚴格遵循:
class One {
One(String s) { System.out.println(s); }
}
class Two {
One o1 = new One("one-1");
One o2 = new One("one-2");
Two(String s) { System.out.println(s); }
}
public class Test {
public static void main(String[] args) {
System.out.println("main start");
new Two("two");
}
}
// 輸出:main start → one-1 → one-2 → two
class Two {
One o1 = new One("one-1");
One o2 = new One("one-2");
static One o3 = new One("one-3"); // 靜態優先
Two(String s) { System.out.println(s); }
}
public class Test {
public static void main(String[] args) {
System.out.println("main start");
new Two("two-1");
System.out.println("----");
new Two("two-2");
}
}
// 輸出:
// main start
// one-3 ← 類別載入時執行,僅一次
// one-1 → one-2 → two-1
// ----
// one-1 → one-2 → two-2 ← 靜態不再執行
super()精確掌握初始化時序,是編寫健壯Java類別、避免隱性Bug的關鍵基礎功夫。