Java 類別宣告形式多樣,各有語義邊界與適用場景。本文系統梳理 9 大類別分類,附語法範例、編譯產物、存取規則、設計意圖與最佳實踐。
| 分類 | 關鍵字/語法 | 定義位置 | 存取外部成員 | 典型用途 |
|---|---|---|---|---|
| 頂層類別 | `class` / `interface` / `enum` / `record` / `sealed class` | 編譯單元 (.java) 直接包含 | 僅同包/公開成員 | 獨立可複用組件、API 邊界 |
| 靜態巢狀類別 | `static class` / `static interface` | 另一個類別內部 | 僅外部類別的靜態成員 | 邏輯歸屬外部類、無需外部實例 (Builder、DTO、策略實作) |
| 非靜態內部類別 | `class` (無 static) | 另一個類別內部 | **隱含持有外部實例引用**,可存取所有外部成員 (含私有) | 迭代器、事件監聽、狀態機節點、需強綁定外部實例 |
| 區域類別 | 方法/建構子/初始化區塊內 `class Name {}` | 區塊內部 | 外部 final/有效 final 區域變數、參數、this | 極局部邏輯封裝、實作介面回傳、複雜算法步驟隔離 |
| 匿名類別 | `new Interface() {}` / `new SuperClass() {}` | 表達式位置 | 同區域類別 | 一次性介面實作、舊版 Lambda 替代、動態代理、測試雙 |
| 密封類別 (JDK 17+) | `sealed class ... permits A, B, C` | 頂層/巢狀 | 同頂層 | **受限繼承體系**:領域建模 (代數資料型別)、狀態機、訊息類型 |
| 記錄類別 (JDK 16+) | `record Name(Type field, ...) {}` | 頂層/巢狀 | 同頂層 | **不可變資料載體**:DTO、值物件、多返回值、模式匹配解構 |
| 枚舉類別 | `enum Name { CONST }` | 頂層/巢狀 | 同頂層 | **固定常數集合**:狀態碼、策略枚舉、單例實作 |
| 抽象類別 | `abstract class` | 頂層/巢狀 | 同頂層 | **部分實作共享**:模板方法、骨架實作、強制子類合約 |
class Outer {
private String outerField = "outer";
static String staticField = "static";
static class StaticNested {
void access() {
System.out.println(staticField); // ✅ 僅靜態
// System.out.println(outerField); // ❌ 編譯錯誤
}
}
class Inner {
void access() {
System.out.println(outerField); // ✅ 隱含 this.outerField
System.out.println(staticField); // ✅
}
}
}
// 實例化差異
Outer.StaticNested sn = new Outer.StaticNested(); // 獨立
Outer.Inner in = new Outer().new Inner(); // 必須有外部實例
記憶體洩漏風險:非靜態內部類別實例隱含持有外部實例引用,若內部實例生命週期 > 外部實例 (如靜態集合緩存、執行緒未結束),將阻礙外部實例 GC。**靜態巢狀類別無此問題**。
void process(List data) {
// 區域類別:有名字、可複用、可多次實例化、可實作多介面
class Filter implements Predicate {
private final Set stopWords = Set.of("the", "a");
public boolean test(String s) { return !stopWords.contains(s); }
}
Filter f = new Filter();
data.stream().filter(f).forEach(System.out::println);
}
// 匿名類別:就地一次性、實作單一介面/擴充單一類
Runnable r = new Runnable() {
@Override public void run() { System.out.println("Running"); }
};
**現代建議**:能用 **Lambda** (函數式介面) 就用 Lambda;需實作多方法介面、存取非 final 區域變數、複雜邏輯 → 區域類別/獨立類別。
sealed interface Expr permits Const, Add, Mul, Var {
// 模式匹配 switch (JDK 21)
static int eval(Expr e) {
return switch (e) {
case Const(int v) -> v;
case Add(Expr l, Expr r) -> eval(l) + eval(r);
case Mul(Expr l, Expr r) -> eval(l) * eval(r);
case Var(String name) -> throw new UnsupportedOperationException("需環境");
};
}
}
record Const(int value) implements Expr {}
record Add(Expr left, Expr right) implements Expr {}
record Mul(Expr left, Expr right) implements Expr {}
record Var(String name) implements Expr {}
優勢:編譯器保證 **窮盡性檢查** (switch 涵蓋所有 permits 子類)、不可變、序列化友善、模式匹配解構極簡潔。
Java 類別分類不只是語法糖,每種形式對應明確的**封裝邊界、生命週期綁定、繼承約束、語義意圖**。掌握 9 大分類特性與決策指南,能寫出結構清晰、語義精確、記憶體安全、易於模式匹配與維護的現代 Java 代碼。