// 正確
switch (priority) {
case HIGH: // 直接用常數名,不可寫 Priority.HIGH
break;
case MEDIUM:
case LOW:
break;
}
// 錯誤:編譯器報錯 "qualified name not allowed"
switch (priority) {
case Priority.HIGH: // 編譯失敗
break;
}

編譯器根據編譯單元採用不同策略:
情況一:同一編譯單元(枚舉定義與 switch 在同源檔或同模組編譯)ordinal())。switch 編譯為 tableswitch 或 lookupswitch 位元組碼指令,直接用 ordinal() 跳轉。int ordinal = priority.ordinal();
switch (ordinal) {
case 0: /* HIGH */ break;
case 1: /* MEDIUM */ break;
case 2: /* LOW */ break;
default: throw new AssertionError("Unexpected enum value!");
}
if-else 鏈:
Priority tmp = priority;
if (tmp == Priority.HIGH) { /* ... */ }
else if (tmp == Priority.MEDIUM) { /* ... */ }
else if (tmp == Priority.LOW) { /* ... */ }
else { throw new AssertionError("Unexpected enum value!"); }
啟示:同模組內使用枚舉 switch 效能最佳;跨模組時仍正確但略有開銷。
java.util.EnumMap<K extends Enum<K>, V> 以陣列為底層,索引直接用 key.ordinal(),完全避開雜湊計算與碰撞處理。
EnumMap<Priority, String> messages = new EnumMap<>(Priority.class);
messages.put(Priority.HIGH, "High means urgent");
messages.put(Priority.MEDIUM, "Medium means normal");
messages.put(Priority.LOW, "Low means deferrable");
for (Priority p : Priority.values()) {
System.out.println("Priority " + p + ": " + messages.get(p));
}
| 指標 | EnumMap | HashMap |
|---|---|---|
| 記憶體 | 極低(單陣列) | 高(Node[] + Entry 物件) |
| get/put | 極快(陣列索引) | 快(雜湊 + 索引 + 碰撞) |
| 迭代順序 | 鍵的宣告順序 | 無序 |
| null 鍵 | 不允許 | 允許一個 |
鐵律:Map 鍵為枚舉類型時,無條件使用 EnumMap。
EnumSet<Color> set = EnumSet.noneOf(Color.class); // 空集合
set.add(Color.RED);
set.addAll(EnumSet.range(Color.BLUE, Color.GREEN));
set.remove(Color.BLUE);
set.removeAll(EnumSet.of(Color.RED));
set.retainAll(EnumSet.complementOf(Color.BLACK)); // 交集
boolean has = set.contains(Color.GREEN);
EnumSet<Color> copy = EnumSet.copyOf(set); // 複製
所有集合運算(聯集、交集、差集、補集)均為位運算,納秒級完成。
EnumMap、EnumSet 建構子需傳入 EnumClass.class,Eclipse 類型推斷可簡化為 new EnumMap<>(Priority.class)(菱形語法 Java 7+)。掌握 switch 不加前綴規則、理解編譯器雙模式實現、熟練運用 EnumMap/EnumSet,是高效、型別安全處理枚舉資料的核心技能組合。