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

Java 枚舉類型完全指南:從基礎常量到多態行為與策略模式實戰

     編輯:Java 相關知識

前言:枚舉不只是常量集合

自 Java 5 引入 enum 關鍵字以來,枚舉已進化為功能強大的「受限類」,不僅能定義固定常量,更支援字段、方法、構造器、介面實現、抽象方法覆寫,甚至能實現策略模式、狀態機等設計模式。本文從基礎語法進階到多態行為、策略封裝,全方位解鎖枚舉的實戰潛力。

一、基礎:類型安全的常量集合


public enum Color {
    GREEN, RED, YELLOW;
    
    public static void main(String[] args) {
        // 遍歷所有常量
        for (Color c : Color.values()) {
            System.out.println("color: " + c);           // 枚舉名
            System.out.println("position: " + c.ordinal()); // 聲明順序 (0-based)
        }
    }
}
/*
輸出:
color: GREEN
position: 0
color: RED
position: 1
color: YELLOW
position: 2
*/

核心優勢:比 public static final int 更安全——編譯器保證變量只能持有枚舉中定義的實例,杜絕非法值。

二、Switch 表達式完美契合(Java 12+ 增強)


public enum Color { GREEN, RED, YELLOW }

public class TrafficLight {
    public static String describe(Color color) {
        // Java 12+ Switch 表達式(箭頭語法,無 fall-through)
        return switch (color) {
            case RED    -> "紅燈:停!";
            case GREEN  -> "綠燈:行!";
            case YELLOW -> "黃燈:等一等!";
        };
    }
    
    // Java 14+ yield 關鍵字(塊語法)
    public static String describeClassic(Color color) {
        return switch (color) {
            case RED -> "紅燈:停!";
            case GREEN -> "綠燈:行!";
            case YELLOW -> {
                System.out.println("注意:黃燈閃爍中...");
                yield "黃燈:等一等!";
            }
        };
    }
}

三、多態行為:每個常量擁有專屬實現

枚舉常量可匿名內部類形式覆寫抽象方法,實現「常量級多態」:


public enum Color {
    GREEN {
        @Override public void action() { System.out.println("綠燈行!"); }
    },
    RED {
        @Override public void action() { System.out.println("紅燈停!"); }
    },
    YELLOW {
        @Override public void action() { System.out.println("黃燈亮了等一等!"); }
    };
    
    // 定義抽象方法,強制每個常量實現
    public abstract void action();
    
    public static void main(String[] args) {
        for (Color c : values()) c.action();
    }
}
/*
輸出:
綠燈行!
紅燈停!
黃燈亮了等一等!
*/

這是策略模式的極簡實現:每個枚舉實例就是一個具體策略,無需額外類文件。

四、攜帶數據:構造器與字段


public enum ColorInfo {
    GREEN("綠色", 0x00FF00),
    RED("紅色", 0xFF0000),
    YELLOW("黃色", 0xFFFF00);
    
    private final String chineseName;
    private final int rgbValue;
    
    // 構造器必須 private(默認即 private)
    ColorInfo(String chineseName, int rgbValue) {
        this.chineseName = chineseName;
        this.rgbValue = rgbValue;
    }
    
    public String getChineseName() { return chineseName; }
    public int getRgbValue() { return rgbValue; }
    
    public static void main(String[] args) {
        for (ColorInfo c : values()) {
            System.out.printf("%s: %s (0x%06X)%n", c, c.chineseName, c.rgbValue);
        }
    }
}

五、實現介面:枚舉即服務提供者


public interface Operation {
    double apply(double a, double b);
}

public enum MathOp implements Operation {
    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 a / b; } };
    
    private final String symbol;
    MathOp(String symbol) { this.symbol = symbol; }
    
    public String getSymbol() { return symbol; }
    
    // 靜態工廠方法:根據符號查找
    public static MathOp fromSymbol(String symbol) {
        for (MathOp op : values()) 
            if (op.symbol.equals(symbol)) return op;
        throw new IllegalArgumentException("Unknown symbol: " + symbol);
    }
}

六、EnumSet 與 EnumMap:高性能專用集合


// EnumSet:位向量實現,極致緊湊高效
Set primaryColors = EnumSet.of(Color.RED, Color.GREEN, Color.BLUE);
Set allColors = EnumSet.allOf(Color.class);
Set nonRed = EnumSet.complementOf(EnumSet.of(Color.RED));

// EnumMap:數組實現,鍵為枚舉時比 HashMap 快數倍
Map colorDesc = new EnumMap<>(Color.class);
colorDesc.put(Color.RED, "熱情");
colorDesc.put(Color.BLUE, "冷靜");

七、進階技巧與最佳實踐

  1. 單例模式最佳實現:enum Singleton { INSTANCE; } 既線程安全、又防反射/序列化破壞,Effective Java 首推方式。
  2. 實現介面而非繼承類:枚舉隱式繼承 java.lang.Enum,不可再繼承類,但可實現多個介面。
  3. 慎用 ordinal():依賴聲明順序脆弱且難維護,優先用顯式字段存儲排序權重。
  4. 文檔註解放在常量上:RED /** 紅色 */, 便於 IDE 懸停提示與 Javadoc 生成。
  5. 避免在構造器中執行複雜邏輯:枚舉初始化發生在類加載階段,可能導致死鎖或副作用。

總結

Java 枚舉遠超「常量列表」——它是受限的、可實例化的、支援多態的類。善用枚舉能讓代碼更類型安全、更自文檔化、更符合開閉原則。從簡單狀態標記到複雜策略封裝,枚舉都是建模領域概念的利器。下次面對「一組固定選項」時,請第一時間想到 enum。

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