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

Java Enum 枚舉完全指南:從基礎到進階用法

     編輯:Java 相關知識

什麼是 Enum?

enum(JDK 1.5+)是一種特殊的類,用於定義固定常量集合。它本質上繼承自 java.lang.Enum,提供類型安全、命名空間隔離、可讀性強的常量管理。

1. 最簡單枚舉


public enum WorkDay {
    Monday, Tuesday, Wednesday, Thursday, Friday; // 逗號分隔,分號結束
}

基本用法


WorkDay day = WorkDay.Wednesday;           // 類型安全賦值
switch (day) {                             // switch 支持 enum (JDK 1.5+)
    case Monday:    System.out.println("週一"); break;
    case Wednesday: System.out.println("週三"); break;
    // ...
}

// 遍歷所有值
for (WorkDay d : WorkDay.values()) {
    System.out.println(d);  // toString() 自動返回名稱
}
System.out.println("元素數量: " + WorkDay.values().length);

// 索引
System.out.println(WorkDay.Monday.ordinal());   // 0
System.out.println(WorkDay.Friday.ordinal());   // 4

// 比較 (實現 Comparable)
System.out.println(WorkDay.Monday.compareTo(WorkDay.Thursday)); // -3
System.out.println(WorkDay.Friday.compareTo(WorkDay.Tuesday));  // 3

2. 帶屬性和方法的枚舉


public enum WeAreJavaer {
    Chinese, Java, Spring, DB2, AIX;  // 枚舉值必須寫在最前面

    private static final String LOCATION = "Javaeye"; // 靜態屬性

    public static WeAreJavaer getInfo() {
        return LOCATION.equals("Javaeye") ? Java : Chinese;
    }
}

// 調用
System.out.println(WeAreJavaer.getInfo()); // Java

3. 帶構造器參數的枚舉(關鍵進階)


public enum People {
    Xiaowang(20), Xiaozhang(32), Xiaoli(50), Xiaogou(21);

    private final int age;  // 必須 final

    // 構造器只能 private 或默認,防止外部實例化
    People(int age) { this.age = age; }

    public int getAge() { return age; }
}

規則:

  • 若賦值,所有枚舉值都必須賦值,且必須提供對應構造器。
  • 構造器隱式 private,外部無法 new People()。

遍歷取值


for (People p : People.values()) {
    System.out.println(p + " 的年齡:" + p.getAge());
}
// 輸出:
// Xiaowang 的年齡:20
// Xiaozhang 的年齡:32
// Xiaoli 的年齡:50
// Xiaogou 的年齡:21

4. 進階模式:策略枚舉


public enum Operation {
    PLUS   { double apply(double x, double y) { return x + y; } },
    MINUS  { double apply(double x, double y) { return x - y; } },
    TIMES  { double apply(double x, double y) { return x * y; } },
    DIVIDE { double apply(double x, double y) { return x / y; } };

    abstract double apply(double x, double y); // 每個常量實現抽象方法
}

// 使用
double result = Operation.PLUS.apply(3, 4); // 7.0

這是「枚舉實現策略模式」的經典範例,消除 switch,擴展新運算只需添加枚舉常量,符合開閉原則。

5. 枚舉實現單例(Effective Java 推薦)


public enum Singleton {
    INSTANCE;
    private Resource resource;
    Singleton() { resource = new Resource(); } // 初始化邏輯
    public Resource getResource() { return resource; }
}
// 使用:Singleton.INSTANCE.getResource()

優勢:簡潔、免費提供序列化機制、絕對防止反射/序列化破壞單例、線程安全(類加載機制保證)。

6. 內置方法速查

方法說明
values()返回所有枚舉值數組(按聲明順序)
valueOf(String name)根據名稱獲取枚舉值,找不到拋異常
ordinal()返回聲明順序索引(從 0 開始)
name()返回枚舉常量名稱(不可覆寫)
toString()默認返回 name(),可覆寫自定義顯示
compareTo(E o)比較 ordinal() 大小

7. 避坑指南

  • 不要依賴 ordinal() 作為持久化/業務標識,增刪枚舉值會導致索引漂移。用自定義字段(如 code)。
  • 枚舉值即單例,線程安全,可直接在併發環境下共享。
  • switch 未覆蓋所有值:JDK 12+ switch expression 強制覆蓋所有情況,編譯期提示,避免漏判。
  • 不可繼承:enum 隱式 final,不能被繼承,但可實現接口。

總結

Java enum 遠不止「常量列表」,它是功能豐富的特殊類:支持字段、方法、構造器、實現接口、抽象方法、單例模式。善用枚舉能讓代碼更類型安全、更易讀、更符合面向對象設計原則。從今天起,替換掉代碼中的 public static final int 常量組吧!

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