Effective Java Item34:用 enum 取代 int 常數
整理Effective Java書中Item 34: Use enum instead of int constant心得筆記
主旨
很多 Java 初學者一開始會用 int 常數(例如 1=小、2=中、3=大)來表示一組固定的狀態。但這種做法其實會讓程式容易出錯、不易維護,也看不出意思。Java 後來加入了 enum(列舉型別),提供更安全、清楚、有彈性的方式來處理這類需求。這篇文章會說明為什麼你應該用 enum 取代 int 常數。
點出問題:int 常數的缺點
用 int 常數的問題有很多,最常見的如下:
// 不推薦的作法:使用 int 常數表示星期幾
public class Day {
public static final int MONDAY = 0;
public static final int TUESDAY = 1;
public static final int WEDNESDAY = 2;
// ...
}
你在寫函式的時候:
public boolean isWeekend(int day) {
return day == 5 || day == 6;
}
但這個函式接受任何 int 值,例如 isWeekend(99) 也會執行,而且不會報錯,這就是「型別不安全」。
另外,如果你要列出所有可能的 day 值、加上 switch 判斷、加上屬性… 全部都得自己手動維護,不但容易出錯,程式也不好讀。
替代方案:用 enum 解決這些問題
列舉型別 enum 是 Java 的語言特性,讓你可以定義一組明確、有限的常數。
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
用法:
public boolean isWeekend(Day day) {
return day == Day.SATURDAY || day == Day.SUNDAY;
}
好處是:
- 型別安全:你只能傳入
Day,不能傳int。 - 可讀性高:看得懂
Day.SATURDAY是什麼意思。 - 可以加上欄位、方法,例如:
public enum Day {
MONDAY(false), TUESDAY(false), WEDNESDAY(false),
THURSDAY(false), FRIDAY(false),
SATURDAY(true), SUNDAY(true);
private final boolean isWeekend;
Day(boolean isWeekend) {
this.isWeekend = isWeekend;
}
public boolean isWeekend() {
return isWeekend;
}
}
用法變得更簡潔又清楚:
if (day.isWeekend()) {
System.out.println("放假啦!");
}
真實世界範例:狀態碼的管理
假設你在做訂單系統,舊作法會是這樣:
public class OrderStatus {
public static final int CREATED = 1;
public static final int PAID = 2;
public static final int SHIPPED = 3;
public static final int CANCELLED = 4;
}
這樣容易搞混,還可能寫出錯誤的數值。
改成 enum:
public enum OrderStatus {
CREATED, PAID, SHIPPED, CANCELLED
}
如果要轉成字串顯示,還可以 override toString(),或是加上欄位:
public enum OrderStatus {
CREATED("待付款"),
PAID("已付款"),
SHIPPED("已出貨"),
CANCELLED("已取消");
private final String displayName;
OrderStatus(String displayName) {
this.displayName = displayName;
}
public String displayName() {
return displayName;
}
}
小結
enum 提供比 int 常數更清楚、更安全的方式來定義一組固定值。它能表達意圖、避免錯誤、減少維護負擔,是 Java 中非常推薦使用的工具。
如果還在用 public static final int 來定義常數,現在就試著用 enum 重構看看吧!讓你的程式更具可讀性與穩定性。
Read other posts