Java 5 引入 enum 關鍵字,不僅提供類型安全的常量,更賦予了枚舉「類」的特性:可擁有欄位、方法、實作介面、甚至每個常量擁有專屬行為。《Thinking in Java》稱其為「優雅而乾淨」的解決方案。本文系統梳理 Enum 核心功能與進階應用模式。
public enum State { ON, OFF }
public class EnumDemo {
public static void main(String[] args) {
// 1. 遍歷
for (State s : State.values()) System.out.println(s.name());
// 2. switch 判斷
State cur = State.OFF;
switch (cur) {
case ON: System.out.println("開啟"); break;
case OFF: System.out.println("關閉"); break;
}
// 3. EnumSet:高效位集合操作
EnumSet<State> set = EnumSet.allOf(State.class);
set.remove(State.OFF);
// 4. EnumMap:鍵為 Enum 的高效 Map
EnumMap<State, String> map = new EnumMap<>(State.class);
map.put(State.ON, "運行中");
map.put(State.OFF, "已停止");
}
}
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(1, 2); // 3.0
interface Calculator { int calc(int a, int b); }
enum Strategy implements Calculator {
ADD { public int calc(int a, int b) { return a + b; } },
SUB { public int calc(int a, int b) { return a - b; } };
}
// 用法
int r = Strategy.ADD.calc(5, 3); // 8
enum Handler {
FIRST { boolean handle(Request r) { return r.level < 5; } },
SECOND { boolean handle(Request r) { return r.level < 10; } },
THIRD { boolean handle(Request r) { return true; } }; // 兜底
abstract boolean handle(Request r);
static void process(Request r) {
for (Handler h : values()) if (h.handle(r)) break;
}
}
enum State {
IDLE {
State next(Event e) { return e == Event.START ? RUNNING : this; }
},
RUNNING {
State next(Event e) { return e == Event.STOP ? IDLE : this; }
};
abstract State next(Event e);
}
| 誤區 | 正確做法 |
|---|---|
用 public static final int 代替 Enum | Enum 提供類型安全、命名空間、可讀性、可序列化 |
| 嘗試繼承 Enum | Enum 隱式繼承 java.lang.Enum,Java 單繼承限制無法再繼承類;改用介面分組 |
| 向上轉型為 Enum 後調用 values() | values() 是編譯器生成的靜態方法,父類無此方法;改用 clazz.getEnumConstants() |
| Enum 當作可變集合增刪元素 | Enum 常量在編譯期固定;動態集合請用 EnumSet 或 List |
ordinal(),無哈希碰撞,效能優於 HashMap。Enum 不只是「列舉常量」,更是受限制的類。善用「常量專屬方法」、「實作介面」、「EnumMap/Set」等特性,能將原本散落在 if-else 或 switch 的邏輯封裝到常量內部,實現高內聚、低耦合的領域模型。下次面對「有限狀態集合」時,請優先考慮 Enum。