首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 列舉類型完整指南:從基本用法到進階封裝行為模式

     編輯:Java 相關知識

為什麼需要列舉?

傳統常數定義存在編譯期無法檢查、型別不安全、命名空間污染等問題。列舉提供型別安全的常數集合,編譯期即可捕獲非法值。

演進歷程對比

階段 1:字串常數(不安全)

public class Student {
    private String grade; // "A"~"E"
    public void setGrade(String grade) {
        if (!grade.matches("[ABCDE]")) throw new RuntimeException("錯誤");
        this.grade = grade;
    }
}
// 呼叫端:s.setGrade("H"); // 編譯通過,執行期才報錯

階段 2:類別模擬列舉(繁瑣)

class Grade {
    private Grade() {}
    public static final Grade A = new Grade();
    public static final Grade B = new Grade();
    // ... C, D, E
}
// 呼叫端:s.setGrade(Grade.A); // 型別安全,但樣板代碼過多

階段 3:enum 關鍵字(標準)

enum Grade { A, B, C, D, E }
// 等價於 final class Grade extends Enum<Grade> { ... }

進階封裝:攜帶屬性與行為

帶屬性的列舉

enum Grade {
    A("100-90"), B("89-80"), C("79-70"), D("69-60"), E("59-0");
    
    private final String range;
    Grade(String range) { this.range = range; }
    public String getRange() { return range; }
}

// 使用
Grade g = Grade.A;
System.out.println(g.getRange()); // 100-90

帶行為的列舉(多態實作)

enum Grade {
    A("100-90") { public String toLevel() { return "優"; } },
    B("89-80")  { public String toLevel() { return "良"; } },
    C("79-70")  { public String toLevel() { return "中"; } },
    D("69-60")  { public String toLevel() { return "可"; } },
    E("59-0")   { public String toLevel() { return "差"; } };
    
    private final String range;
    Grade(String range) { this.range = range; }
    public String getRange() { return range; }
    public abstract String toLevel(); // 強制每個常數實作
}

// 使用
System.out.println(Grade.A.toLevel()); // 優
System.out.println(Grade.E.toLevel()); // 差

列舉特性總結

  1. 列舉是特殊的 final class 繼承 java.lang.Enum
  2. 每個列舉常數是該類別的單一實例(單例模式)
  3. 可宣告欄位、方法、建構子(private)
  4. 可實作介面、不可繼承類別
  5. switch 支援列舉型別(Java 5+)
  6. 單元素列舉 = 最佳單例實作方式

常用方法速查

Grade g = Grade.valueOf("B");  // 字串轉列舉,不存在拋 IllegalArgumentException
String name = g.name();        // 獲取常數名稱 "B"
int ordinal = g.ordinal();     // 宣告順序 0-based
Grade[] all = Grade.values();  // 所有常數陣列
for (Grade gr : all) {
    System.out.println(gr.name() + "=" + gr.ordinal());
}

實務設計模式應用

  • 策略模式:每個列舉常數實作不同演算法行為
  • 狀態機:列舉常數代表狀態,方法定義轉換邏輯
  • 命令模式:列舉封裝命令執行邏輯
  • 單例:enum Singleton { INSTANCE; } 防反射/序列化破壞

序列化注意

列舉序列化只儲存常數名稱,反序列化時由 JVM 保證單一實例,不需實作 Serializable 介面,天生安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved