使用列舉ENUM替換Switch或If-Else
Switch/case是在大多數指令式程式設計語言中實現的通用控制結構。Switch被認為比if/else系列更具可讀性。
這是一個簡單的例子:
switch (c) { case 1: one(); break; case 2: two(); break; case 3: three(); break; default: throw new UnsupportedOperationException(String.format("Operation %d is not supported", c)); } |
以下是此程式碼中的主要問題列表:
- int型別的字元號(1,2,3)和執行的程式碼之間的關係並不明顯。
- 如果其中一個值(例如2)不再受支援,並且此switch未相應更新,則它將永遠包含未使用的程式碼。
- 如果引入了新的可能值c(例如4)並且Swtich沒有相應更新,則程式碼可能會在執行時丟擲UnsupportedOperationException,而不會在編譯時發生任何通知。
- 這種Switch結構往往在程式碼中被重複多次,使問題2和3更加複雜。
使用int變數可以簡單解決:
private static int ONE = 1; private static int TWO = 2; private static int THREE = 3; |
那麼程式碼成為下面這樣:
switch (c) { case ONE: one(); break; case TWO: two(); break; case THREE: three(); break; default: throw new UnsupportedOperationException(String.format("Operation %d is not supported", c)); } |
(顯然在現實生活中,常量的名稱必須是自描述的)這個片段更具可讀性,但所有其他缺點仍然相關。
列舉Enum
進一步改進初始程式碼片段的嘗試是使用2004年版本5中引入Java語言的列舉。
讓我們定義以下列舉:
enum Action {ONE, TWO, THREE} |
現在,Switch程式碼段會略有變化:
Action a = ... switch (a) { case ONE: one(); break; case TWO: two(); break; case THREE: three(); break; default: throw new UnsupportedOperationException(String.format("Operation %s is not supported", a)); } |
這段程式碼更好一點:如果從列舉Action中刪除了其中一個元素,它將產生編譯錯誤。 但是,如果向列舉Action新增了其他元素,則不會導致編譯錯誤 。 在這種情況下,某些IDE或靜態程式碼分析工具可能會產生警告,但是誰會關注警告你?幸運的是,列舉可以宣告必須由每個元素實現的抽象方法:
enum Action { ONE { @Override public void action() { } }, TWO { @Override public void action() { } }, THREE { @Override public void action() { } }, public abstract void action(); } |
現在switch語句可以替換為單行:
Action a = ... a.action(); |
該解決方案沒有上面列舉的任何缺點:
- 它是可讀的。該方法被“附加”到列舉元素; 如果方法含義不清楚,可以根據需要編寫儘可能多的javadoc。呼叫方法的程式碼是微不足道的:什麼可以比方法呼叫更簡單?
- 如果不刪除實現,就無法刪除 列舉常量,因此如果某些功能不再相關,則不會保留未使用的程式碼。
- 如果沒有實現方法action(),則無法新增新的 列舉元素。沒有實現的程式碼會無法編譯。
- 如果需要多個操作,則可以在列舉中實現所有操作 。正如我們已經提到的,呼叫特定函式的程式碼是微不足道的,所以現在沒有程式碼重複。
相關文章
- Java 列舉(enum)Java
- TypeScript 列舉enumTypeScript
- ENUM列舉型別型別
- 【python】Enum 列舉類Python
- Java —— 列舉類(enum 類)Java
- 再談java列舉enumJava
- Java - Enum 列舉型別Java型別
- Java 列舉 enum 詳解Java
- Rust的列舉型別EnumRust型別
- 聊聊TypeScript中列舉物件(Enum)TypeScript物件
- Java列舉型別enum的詳解及使用Java型別
- Java enum列舉類詳解 列舉的常見用法Java
- 從JDK角度認識列舉enumJDK
- 聊一聊Java的列舉enumJava
- Java 列舉 switch的用法Java
- 優雅使用前端列舉Enum,符合國標的那種!前端
- Java列舉enum可以有抽象方法! -RecepİnançJava抽象NaN
- Java列舉:小小enum,優雅而乾淨Java
- 條款02: 儘量以const,enum,inline 替換 #defineinline
- 我在大廠做 CR——為什麼建議使用列舉來替換布林值
- 【C/C++】C和C++11之enum列舉的使用細節C++
- PLC結構化文字(ST)——隱式列舉(implicit enum)
- Java 列舉(enum) 詳解7種常見的用法Java
- Enum列舉型別實戰總結,保證有用!型別
- 列舉的幾種使用案例(簡單,進階,switch,單例)單例
- 資料結構複習-01enum列舉型別資料結構型別
- 為什麼使用列舉作為配置項(enum as configuration)是反開發模式的模式
- 策略列舉:消除在專案裡大批量使用if-else的正確姿勢
- C# enum列舉為0的時候不需要強制轉換,很容易掉坑C#
- c#列舉轉換C#
- 消除程式碼中的 if-else/switch-case
- pandas列值根據字典批量替換
- c++11 實現列舉值到列舉名的轉換C++
- 【java】【列舉使用技巧】Java
- 定積分之換元積分法公式(或稱變數替換法)公式變數
- Redis 中使用 scan 替換 keysRedis
- Aspose.Words for .NET如何替換或修改超連結
- Python 在PDF中新增、替換、或刪除圖片Python