使用列舉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
- Java 列舉(enum)Java
- ENUM列舉型別型別
- iOS - OC Enum 列舉iOS
- java enum(列舉)使用詳解 + 總結Java
- Java - Enum 列舉型別Java型別
- Java —— 列舉類(enum 類)Java
- Java 列舉 enum 詳解Java
- java基礎:enum列舉Java
- 再談java列舉enumJava
- 【python】Enum 列舉類Python
- JAVA 基礎 - ENUM 列舉的簡單使用Java
- 聊聊TypeScript中列舉物件(Enum)TypeScript物件
- mysql之ENUM列舉型別MySql型別
- 認知列舉(C# Enum)C#
- Rust的列舉型別EnumRust型別
- Java列舉型別enum的詳解及使用Java型別
- Java enum列舉類詳解 列舉的常見用法Java
- 從JDK角度認識列舉enumJDK
- 聊一聊Java的列舉enumJava
- 優雅使用前端列舉Enum,符合國標的那種!前端
- Java 列舉 switch的用法Java
- 透過列舉enum實現單例單例
- C++typedef宣告,enum列舉型別C++型別
- Kotlin-17.列舉類(enum class)Kotlin
- Java enum 列舉還可以這麼用Java
- C/C++列舉enum分別列印輸出列舉子和列舉值的方法C++
- Java列舉enum可以有抽象方法! -RecepİnançJava抽象NaN
- Java列舉:小小enum,優雅而乾淨Java
- 關於Java中列舉Enum的深入剖析Java
- 我在大廠做 CR——為什麼建議使用列舉來替換布林值
- 【C/C++】C和C++11之enum列舉的使用細節C++
- 【02】儘量以const,enum,inline替換#defineinline
- Enum列舉型別實戰總結,保證有用!型別
- Java 列舉(enum) 詳解7種常見的用法Java
- C# Enum列舉型別操作擴充套件類C#型別套件
- PLC結構化文字(ST)——隱式列舉(implicit enum)