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

Java Enum 枚舉類型完全指南:定義、遍歷、自定義屬性方法、EnumSet/Map 實戰

     編輯:Java 綜合教學

為什麼用 Enum?

替代 public static final int MON = 1; 等「整型枚舉模式」,提供:

  • 類型安全:編譯期防止非法值傳入
  • 命名空間隔離:Day.MON 不會污染全局
  • 豐富行為:可攜帶字段、方法、實現接口
  • 單例保證:JVM 保證每個枚舉常量在類加載器中唯一

基本定義與編譯原理

public enum Day {
    MON, TUE, WED, THU, FRI, SAT, SUN;
}

編譯後生成 final class Day extends Enum<Day>,每個常量是 public static final Day MON = new Day("MON", 0);。構造函數 protected Enum(String name, int ordinal) 自動賦值名稱與順序。

常用操作

遍歷

for (Day d : Day.values()) {
    System.out.println(d.name() + " -> " + d.ordinal());
}

Switch 表達式(Java 12+)

String cn = switch (day) {
    case MON -> "星期一";
    case TUE -> "星期二";
    default -> day.name();
};

值轉換

Day d = Day.valueOf("MON"); // 字符串轉枚舉,區分大小寫
int idx = d.ordinal();       // 0-based 索引
String name = d.name();      // 常量名

自定義字段、構造器、方法

public enum Day {
    MON("星期一", 1), TUE("星期二", 2), WED("星期三", 3),
    THU("星期四", 4), FRI("星期五", 5), SAT("星期六", 6), SUN("星期日", 7);

    private final String chineseName;
    private final int index;

    Day(String chineseName, int index) {
        this.chineseName = chineseName;
        this.index = index;
    }

    public String getChineseName() { return chineseName; }
    public int getIndex() { return index; }

    // 靜態查找方法
    public static Day fromIndex(int index) {
        for (Day d : values()) if (d.index == index) return d;
        throw new IllegalArgumentException("Invalid index: " + index);
    }

    @Override
    public String toString() { return index + "_" + chineseName; }
}

實現接口(多態行為)

public interface WorkSchedule {
    boolean isWorkDay();
}

public enum Day implements WorkSchedule {
    MON(true), TUE(true), WED(true), THU(true), FRI(true), SAT(false), SUN(false);

    private final boolean workDay;
    Day(boolean workDay) { this.workDay = workDay; }
    @Override public boolean isWorkDay() { return workDay; }
}

EnumSet & EnumMap:高性能專用集合

EnumSet(位向量實現,極快)

// 工作日集合
EnumSet workDays = EnumSet.range(Day.MON, Day.FRI);
// 週末
EnumSet weekend = EnumSet.complementOf(workDays);
// 遍歷
for (Day d : workDays) System.out.println(d);

EnumMap(數組實現,鍵為枚舉)

EnumMap schedule = new EnumMap<>(Day.class);
schedule.put(Day.MON, "會議");
schedule.put(Day.FRI, "總結");
schedule.forEach((k, v) -> System.out.println(k + " -> " + v));

進階技巧與最佳實踐

  1. 單例模式最佳實現:public enum Singleton { INSTANCE; } —— 線程安全、防反序列化破壞、防反射攻擊。
  2. 策略模式:每個枚舉常量實現不同算法行為。
  3. 狀態機:枚舉常量持有狀態轉移邏輯。
  4. 避免在枚舉中進行耗時初始化,類加載時會執行所有常量構造器。
  5. 序列化自動處理:JVM 保證反序列化返回同一常量實例,無需 readResolve。

常見誤區

❌ 嘗試繼承枚舉
Enum 隱式 final,不可繼承(但可實現接口)。
❌ 構造器設為 public
構造器只能是 private 或 package-private,JVM 內部調用。
❌ 依賴 ordinal() 做持久化
新增常量會改變順序,導致數據錯位。持久化請用 name() 或自定義 code 字段。

總結

Java Enum 是「類」與「常量」的完美融合:**它是類,所以能攜帶行為;它是常量,所以天然單例、類型安全**。掌握 EnumSet/Map、接口實現、單例模式等進階用法,能讓你的代碼更簡潔、更健壯、更具表達力。下次看到一堆 public static final int 時,請毫不猶豫地重構為 Enum。

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