jdk switch 枚举_JDK 12开关表达式遇到意外的枚举值
jdk switch 枚舉
正如我在“ 玩JDK 12的Switch表達式 ”一文中所寫的那樣, JDK 12 Early Access Build使JEP 325 [“ Switch Expressions(Preview)”)實現的實驗變得容易。 我的帖子“ JDK 12:實際中的切換語句/表達式 ”使用代碼示例來演示增強的switch 語句和新的switch 表達式的核心特征。 在本文中,我將介紹在JEP 325中顯式調用的一種特殊情況,該特殊情況與在運行時添加到switch表達式中的枚舉有關。
因為switch 表達式返回一個值,所以必須通過case處理該switch可能遇到的所有可能case (或對于那些未與case明確關聯的case default將其覆蓋)。 JEP 325規定如下:
switch表達式的情況必須詳盡無遺; 對于任何可能的值,必須有一個匹配的開關標簽。 實際上,這通常僅意味著需要一個默認子句。 但是,在枚舉開關表達式涵蓋所有已知情況的情況下(最終,開關表達式通過密封類型),編譯器可以插入默認子句,該子句指示枚舉定義在編譯時和運行時之間已更改。 (這是開發人員今天手動執行的操作,但是讓編譯器插入它比手動編寫的代碼更具侵入性,并且可能具有更具描述性的錯誤消息。)
我已經寫了類似于JEP 325中描述的代碼(“這就是開發人員今天要做的事情”),正如我在博客文章“ 記錄意外的開關選項 ”中所討論的那樣。 過去,通常明智的做法是添加邏輯來處理或記錄未在default顯式調用或處理的switch語句選項。 隨著通過JDK 12和JEP 325的switch表達式的出現,現在是必需的。
JEP 325解決了枚舉上的switch 表達式的情況,并明確指定了如何支持在編譯帶有switch表達式的枚舉和代碼的case在case子句中顯式指定了所有枚舉值的case ,但后來又添加了更多的值到枚舉,而無需使用該枚舉重新編譯switch表達式代碼。
為了展示這種支持,我將展示一個簡單的枚舉以及兩個基于JEP 325和JDK Early Access Build 10的示例,以便在switch 語句和switch 表達式中使用該枚舉。
下面的代碼清單顯示了一個簡單的枚舉,稱為Response ,只有兩個值。
package dustin.examples.jdk12.switchexp;/*** Enum representation of a response.*/ public enum Response {YES,NO; }下一個代碼清單顯示了一個類,其中包含使用上述枚舉的兩個方法。 一種方法針對該枚舉使用switch 語句 ,另一種方法針對該枚舉使用switch 表達式 。
package dustin.examples.jdk12.switchexp;import static java.lang.System.out;/*** Demonstrates implicit handling of expanding enum* definition related to JEP 325 switch expressions and* switch statements.*/ public class GrowingEnumSwitchDemo {public static void printResponseStringFromStatement(final Response response){out.println("Statement [" + response.name() + "]:");switch (response){case YES:out.println("Si!");break;case NO:out.println("No!");break;}}public static void printResponseStringFromExpression(final Response response){out.println("Expression [" + response.name() + "]:");out.println(switch (response){case YES -> "Si!";case NO -> "No!";});}public static void main(final String[] arguments){if (arguments.length < 1){out.println("Provide an appropriate 'dustin.examples.jdk12.switchexp.Response' string as an argument.");System.exit(-1);}final String responseString = arguments[0];out.println("Processing string '" + responseString + "'.");final Response response = Response.valueOf(responseString);printResponseStringFromStatement(response);printResponseStringFromExpression(response);} }上面的代碼( 在GitHub上也可用 )將編譯而不會發生意外,并且當我在GrowingEnumSwitchDemo類上執行main函數并將其傳遞給“ YES”字符串時,它將按預期工作。 如果我向Response枚舉添加一個新值MAYBE并僅編譯該枚舉Java文件 ,然后使用字符串“ MAYBE”運行GrowingEnumSwitchDemo.main(String[]) , GrowingEnumSwitchDemo.main(String[])遇到IncompatibleClassChangeError 。 接下來顯示新的Response.java清單,然后是屏幕快照,該屏幕快照演示了僅用新值重新編譯枚舉并使用先前編譯的調用代碼運行后,剛剛描述的問題。
package dustin.examples.jdk12.switchexp;/*** Enum representation of a response.*/ public enum Response {YES,NO,MAYBE; }
IncompatibleClassChangeError的存在使我們很明顯地發現,枚舉上有一個新值,該值以前沒有由switch表達式處理。 這使開發人員可以通過添加枚舉值的case或添加全包式default來修復switch表達式。 這可能會比今天的當前情況更好,在當前情況下,使用: / break語法的switch語句將在相同情況下無提示地繼續運行(在先前的代碼清單和屏幕快照中也得到了證明)。
關于通過JEP 325引入Java的增強功能,有幾件令人喜歡的事情。“箭頭”語法使switch 表達式和switch 語句不必承受令人驚訝的范圍問題,無意跌倒的風險或需要明確的break s的負擔。 此外,必須返回值的switch 表達式可以與枚舉結合使用,以確保所有枚舉值始終在編譯時進行處理(如果并非在編譯時處理所有枚舉值,則不會進行編譯)如果使用的枚舉添加了一個值并與先前編譯的客戶端代碼一起使用,則會引發錯誤。
翻譯自: https://www.javacodegeeks.com/2018/09/jdk-12-switch-expression-encountering-unanticipated-enum-value.html
jdk switch 枚舉
總結
以上是生活随笔為你收集整理的jdk switch 枚举_JDK 12开关表达式遇到意外的枚举值的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: spring boot分层_只需5分钟即
- 下一篇: react 线程_React式服务中的线