Effective Java Item35:請用實例欄位而非 ordinal()
整理Effective Java書中Item 35: Use instance fields instead of ordinals心得筆記
主旨
雖然 enum.ordinal()
這個方法看起來很方便,可以讓你直接取得列舉常數的順序編號,但實際上使用它來表示邏輯意義是非常危險的作法。這一則要點告訴我們:如果你需要用 enum 來代表某種數值或邏輯資訊,應該用實例欄位來明確定義,而不要依賴 ordinal() 的數字順序。
點出問題:ordinal() 表面簡單,其實是地雷
我們先來看一個錯誤使用 ordinal() 的例子:
乍看之下沒什麼問題,但如果未來有一天你需要調整 enum 的順序,例如把 HIGH 放到最前面,結果 danger 的值也會變成 0,導致整個邏輯大錯特錯,而且這種 bug 不容易察覺。
這種「依賴順序」的設計,未來只要有人「整理一下 enum 順序」都可能造成災難。
範例:用實例欄位更穩定
正確做法是這樣,透過建構子和欄位明確定義每個常數對應的值:
這樣一來就算你把 HIGH 搬到最前面,也不會影響邏輯,因為 dangerValue 是明確設定的:
小結
使用 ordinal()
雖然方便,但它不是為了邏輯用途而設計的,而是為了內部 JVM 使用或做排序時使用的。如果你用它來判斷值或做資料儲存,一旦 enum 的順序改變,你的程式就會壞掉。
✅ 該怎麼做:
- 如果 enum 常數需要有數值意義(例如危險程度、顯示順序、代碼),請用實例欄位定義。
- 請避免使用
ordinal()
做為資料儲存或邏輯條件依據。 - 對外暴露資料時,也應該使用自定義欄位,而非
ordinal()
。
Read other posts