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

Java 枚舉類型 enum 完整指南:從基礎到進階實戰

     編輯:Java 相關知識

枚舉類型簡介

JDK 1.5 引入 enum 關鍵字,提供類型安全的枚舉實現。枚舉是一種特殊的類,隱式繼承 java.lang.Enum,不可被繼承,所有實例必須在首行顯式聲明。

核心語法與特性

public enum TrafficLight {
    // 1. 實例必須在第一行聲明,編譯器自動加 public static final
    RED("紅燈", 30), 
    YELLOW("黃燈", 3), 
    GREEN("綠燈", 25);
    
    // 2. 實例欄位
    private final String name;
    private final int durationSeconds;
    
    // 3. 建構子必須 private(隱式 private)
    TrafficLight(String name, int durationSeconds) {
        this.name = name;
        this.durationSeconds = durationSeconds;
    }
    
    // 4. 實例方法
    public String getName() { return name; }
    public int getDuration() { return durationSeconds; }
    
    // 5. 可實現介面
    public void action() {
        switch (this) {
            case RED: System.out.println("停車等候"); break;
            case YELLOW: System.out.println("減速慢行"); break;
            case GREEN: System.out.println("通行"); break;
        }
    }
    
    // 6. 靜態工廠方法
    public static TrafficLight fromName(String name) {
        for (TrafficLight light : values()) {
            if (light.name.equals(name)) return light;
        }
        throw new IllegalArgumentException("未知燈號: " + name);
    }
}

Enum 提供的核心方法

進階用法模式

策略模式:每個實例不同行為

public enum Calculator {
    ADD("+") { public double apply(double a, double b) { return a + b; }},
    SUB("-") { public double apply(double a, double b) { return a - b; }},
    MUL("*") { public double apply(double a, double b) { return a * b; }},
    DIV("/") { public double apply(double a, double b) { return b != 0 ? a / b : Double.NaN; }};
    
    private final String symbol;
    Calculator(String symbol) { this.symbol = symbol; }
    public abstract double apply(double a, double b);
    public String getSymbol() { return symbol; }
}

實現介面:多態行為

public interface State {
    void handle(Context ctx);
}

public enum OrderState implements State {
    PENDING { public void handle(Context ctx) { ctx.pay(); }},
    PAID { public void handle(Context ctx) { ctx.ship(); }},
    SHIPPED { public void handle(Context ctx) { ctx.deliver(); }},
    DELIVERED { public void handle(Context ctx) { /* 完成 */ }};
}

單例模式:最佳單例實現

public enum Singleton {
    INSTANCE;
    
    private Resource resource;
    
    Singleton() {
        resource = new Resource(); // 延遲初始化,線程安全
    }
    
    public Resource getResource() { return resource; }
}

EnumSet 與 EnumMap:高效專用集合


// EnumSet:位向量實現,極快,替代位運算
EnumSet rushHour = EnumSet.of(GREEN, YELLOW);
EnumSet all = EnumSet.allOf(TrafficLight.class);
EnumSet none = EnumSet.noneOf(TrafficLight.class);

// EnumMap:陣列實現,鍵為枚舉時比 HashMap 快數倍
EnumMap chineseNames = new EnumMap<>(TrafficLight.class);
chineseNames.put(RED, "紅燈");
chineseNames.put(GREEN, "綠燈");

序列化與持久化注意事項

  • 枚舉序列化機制特殊:僅序列化 name,反序列化時調用 valueOf
  • 不需實現 Serializable 介面,自動支援
  • 資料庫存儲建議存 name()(字串)或 ordinal()(整數),前者可讀性強,後者空間省
  • 新增枚舉值只能在末尾添加,否則 ordinal() 變化導致持久化數據錯位

最佳實踐總結

  • 替代 public static final int 常量,提供類型安全
  • 單例模式首選 enum 實現
  • 狀態機、策略模式優先考慮枚舉
  • 集合操作使用 EnumSet/EnumMap
  • switch 表達式(Java 12+)完美配合枚舉,編譯器檢查窮盡性
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方法說明範例
values()返回所有實例陣列(編譯器生成)TrafficLight[] lights = TrafficLight.values();
valueOf(String)根據名稱獲取實例,區分大小寫TrafficLight.RED == TrafficLight.valueOf("RED")
ordinal()返回聲明順序索引(從 0 開始)RED.ordinal() == 0
name()返回實例名稱(final,不可覆寫)RED.name() == "RED"
compareTo(E)比較聲明順序RED.compareTo(GREEN) < 0