構造器雖語法類似方法,但本質迥異。正如鴨嘴獸雖屬哺乳動物卻產卵,構造器雖被調用卻無返回值、不可繼承、命名規則特殊。釐清構造器與方法的差異,是 Java 進階與認證考試的必修課。
| 維度 | 構造器 | 方法 |
|---|---|---|
| 目的 | 建立類的實例(new ClassName()) | 執行業務邏輯代碼 |
| 修飾符 | 可用存取修飾符;不可用 abstract、final、native、static、synchronized | 可用所有修飾符 |
| 返回類型 | 無返回類型(連 void 都不寫) | 必須宣告返回類型或 void |
| 命名規則 | 必須與類名完全相同(通常大寫開頭,名詞) | 慣用小寫開頭(動詞或動詞短語) |
| this 用法 | 調用本類其他構造器(必須置於第一行) | 引用當前執行實例;static 方法不可用 |
| super 用法 | 調用父類構造器(必須置於第一行) | 調用父類被覆寫方法(可置於任意位置) |
| 繼承性 | 不可繼承;子類不自動獲得父類構造器 | 可繼承;子類自動擁有父類非 private 方法 |
| 編譯器隱式行為 | 無構造器時自動生成無參構造器;首行無 this()/super() 時自動插入 super() | 無隱式生成 |
public class Platypus {
String name;
public Platypus(String input) {
this.name = input;
}
public Platypus() {
this("John/Mary Doe"); // 必須第一行,委派給帶參構造器
}
}
若非首行編譯報錯。此機制實現構造器邏輯複用,避免重複初始化代碼。
class Mammal {
Mammal() { System.out.println("Mammal init"); }
}
class Platypus extends Mammal {
Platypus() {
super(); // 顯式調用父類無參構造器,必須第一行
System.out.println("Platypus init");
}
}
若父類無無參構造器,子類必須顯式調用帶參 super(...),否則編譯失敗。
// 原始碼
public class Example {}
// 編譯器實際生成
public class Example {
Example() {
super(); // 隱式插入
}
}
這解釋了為什麼所有類最終都能追溯到 Object 的無參構造器。
class Parent {
Parent() { System.out.println("Parent ctor"); }
void sayHi() { System.out.println("Hi"); }
}
class Child extends Parent {
// 無構造器
}
public class Test {
public static void main(String[] args) {
Child c = new Child(); // 輸出 "Parent ctor" —— 調用的是編譯器生成的 Child() { super(); }
c.sayHi(); // 輸出 "Hi" —— 繼承了方法
}
}
子類不繼承父類構造器,而是由編譯器生成預設構造器並鏈式調用父類構造器。
this() 實現構造器鏈,集中初始化邏輯於「主構造器」(參數最全者)。this 引用。構造器是物件誕生的「產房」,而非行為的「方法」。掌握其命名約束、修飾符限制、this()/super() 鏈調用規則、編譯器隱式行為與不可繼承本質,能避開大量初學者常見陷阱,編寫出更健壯、可維護的 Java 類別設計。