現象
public class Animal {
public Animal() { } // 這行似乎多餘?
public void cry() { System.out.print("crying"); }
}
核心原因:繼承鏈上的建構子調用規則
- **子類實例化時,必須先調用父類的無參建構子**(隱式 `super()`)。
- 若父類**僅定義了帶參建構子**(如 `public Animal(String name)`),編譯器**不會自動生成無參建構子**。
- 此時子類若不在建構子首行顯式 `super(參數)`,編譯報錯:`Implicit super constructor Animal() is undefined`。
- 在父類顯式加上 `public Animal() {}`,即提供了無參建構子,子類可隱式調用,編譯通過。
最佳實踐
- **習慣在類中顯式提供無參建構子**,除非刻意禁止無參實例化(如單例、必須帶參初始化)。
- 若父類有多個建構子,子類建構子首行用 `super(...)` 明確指定調用哪個,避免歧義。
- 使用 Lombok `@NoArgsConstructor` 可自動生成,減少樣板代碼。
總結
「多餘」的 `public Animal() {}` 實際上是**為了繼承體系的正常運作而預留的無參建構子**,是良好的防禦性編程習慣。