自 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 更安全——編譯器保證變量只能持有枚舉中定義的實例,杜絕非法值。
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:位向量實現,極致緊湊高效
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, "冷靜");
enum Singleton { INSTANCE; } 既線程安全、又防反射/序列化破壞,Effective Java 首推方式。java.lang.Enum,不可再繼承類,但可實現多個介面。RED /** 紅色 */, 便於 IDE 懸停提示與 Javadoc 生成。Java 枚舉遠超「常量列表」——它是受限的、可實例化的、支援多態的類。善用枚舉能讓代碼更類型安全、更自文檔化、更符合開閉原則。從簡單狀態標記到複雜策略封裝,枚舉都是建模領域概念的利器。下次面對「一組固定選項」時,請第一時間想到 enum。