Effective Java Item36:請用 EnumSet 取代位元欄位
整理Effective Java書中Item 36: Use EnumSet instead of bit fields心得筆記
主旨
在 Java 裡,用 int 或 long 表示多種布林選項的做法已經過時了,這種設計方式可讀性差又容易出錯。現在有更好的選擇 —— EnumSet。它不但語意清楚、效能高,而且更安全、好維護。
點出問題:傳統寫法的缺點
假設你要開發一個露營網站,使用者可以選擇多種活動(像是烤肉、划船、夜間觀星、登山健行等)。如果你用傳統的位元欄位來記錄活動選項,可能會這樣寫:
public class ActivityOld {
public static final int BBQ = 1 << 0;
public static final int BOATING = 1 << 1;
public static final int STARGAZING = 1 << 2;
public static final int HIKING = 1 << 3;
}
// 使用方式:
int selectedActivities = ActivityOld.BBQ | ActivityOld.HIKING;
問題在哪裡?
- 看不懂
1 << 2是什麼活動 - 要新增活動要小心選位元,超過 32/64 還要換型別
- 沒有型別安全檢查,可能誤用錯值
- 可讀性與維護性差
範例:用 EnumSet 改寫更清楚
public enum Activity {
BBQ, BOATING, STARGAZING, HIKING
}
public class CampReservation {
private EnumSet<Activity> activities;
public CampReservation(EnumSet<Activity> activities) {
this.activities = activities;
}
public boolean includes(Activity activity) {
return activities.contains(activity);
}
public void printActivities() {
for (Activity activity : activities) {
System.out.println("參加活動:" + activity);
}
}
}
使用方式:
CampReservation reservation = new CampReservation(EnumSet.of(
Activity.BBQ, Activity.HIKING));
reservation.printActivities();
// 輸出:
// 參加活動:BBQ
// 參加活動:HIKING
劃重點
EnumSet是針對 enum 設計的高效集合,底層就是用位元實作,但不暴露實作細節。- 可讀性與型別安全性都比
int常數高。 - 新增活動時,只要在 enum 裡加一項,其他程式不用動。
- 若活動超過 64 個,
EnumSet也能自動從RegularEnumSet轉成JumboEnumSet處理,不需手動改型別。
小結
如果需要表示「多種 enum 狀態可同時成立」,請不要再用 int 或 long 自己拼位元欄位了。EnumSet 提供了更簡單、更穩、更直覺的解法,不只能讓程式碼更清楚,也能減少錯誤與未來維護負擔。未來遇到類似需求時,第一個該想到的就是 EnumSet!
Read other posts