jdk switch 枚举_JDK 12开关表达式遇到意外的枚举值
jdk switch 枚舉
正如我在“ 玩JDK 12的Switch表達(dá)式 ”一文中所寫(xiě)的那樣, JDK 12 Early Access Build使JEP 325 [“ Switch Expressions(Preview)”)實(shí)現(xiàn)的實(shí)驗(yàn)變得容易。 我的帖子“ JDK 12:實(shí)際中的切換語(yǔ)句/表達(dá)式 ”使用代碼示例來(lái)演示增強(qiáng)的switch 語(yǔ)句和新的switch 表達(dá)式的核心特征。 在本文中,我將介紹在JEP 325中顯式調(diào)用的一種特殊情況,該特殊情況與在運(yùn)行時(shí)添加到switch表達(dá)式中的枚舉有關(guān)。
因?yàn)閟witch 表達(dá)式返回一個(gè)值,所以必須通過(guò)case處理該switch可能遇到的所有可能case (或?qū)τ谀切┪磁ccase明確關(guān)聯(lián)的case default將其覆蓋)。 JEP 325規(guī)定如下:
switch表達(dá)式的情況必須詳盡無(wú)遺; 對(duì)于任何可能的值,必須有一個(gè)匹配的開(kāi)關(guān)標(biāo)簽。 實(shí)際上,這通常僅意味著需要一個(gè)默認(rèn)子句。 但是,在枚舉開(kāi)關(guān)表達(dá)式涵蓋所有已知情況的情況下(最終,開(kāi)關(guān)表達(dá)式通過(guò)密封類(lèi)型),編譯器可以插入默認(rèn)子句,該子句指示枚舉定義在編譯時(shí)和運(yùn)行時(shí)之間已更改。 (這是開(kāi)發(fā)人員今天手動(dòng)執(zhí)行的操作,但是讓編譯器插入它比手動(dòng)編寫(xiě)的代碼更具侵入性,并且可能具有更具描述性的錯(cuò)誤消息。)
我已經(jīng)寫(xiě)了類(lèi)似于JEP 325中描述的代碼(“這就是開(kāi)發(fā)人員今天要做的事情”),正如我在博客文章“ 記錄意外的開(kāi)關(guān)選項(xiàng) ”中所討論的那樣。 過(guò)去,通常明智的做法是添加邏輯來(lái)處理或記錄未在default顯式調(diào)用或處理的switch語(yǔ)句選項(xiàng)。 隨著通過(guò)JDK 12和JEP 325的switch表達(dá)式的出現(xiàn),現(xiàn)在是必需的。
JEP 325解決了枚舉上的switch 表達(dá)式的情況,并明確指定了如何支持在編譯帶有switch表達(dá)式的枚舉和代碼的case在case子句中顯式指定了所有枚舉值的case ,但后來(lái)又添加了更多的值到枚舉,而無(wú)需使用該枚舉重新編譯switch表達(dá)式代碼。
為了展示這種支持,我將展示一個(gè)簡(jiǎn)單的枚舉以及兩個(gè)基于JEP 325和JDK Early Access Build 10的示例,以便在switch 語(yǔ)句和switch 表達(dá)式中使用該枚舉。
下面的代碼清單顯示了一個(gè)簡(jiǎn)單的枚舉,稱(chēng)為Response ,只有兩個(gè)值。
package dustin.examples.jdk12.switchexp;/*** Enum representation of a response.*/ public enum Response {YES,NO; }下一個(gè)代碼清單顯示了一個(gè)類(lèi),其中包含使用上述枚舉的兩個(gè)方法。 一種方法針對(duì)該枚舉使用switch 語(yǔ)句 ,另一種方法針對(duì)該枚舉使用switch 表達(dá)式 。
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上也可用 )將編譯而不會(huì)發(fā)生意外,并且當(dāng)我在GrowingEnumSwitchDemo類(lèi)上執(zhí)行main函數(shù)并將其傳遞給“ YES”字符串時(shí),它將按預(yù)期工作。 如果我向Response枚舉添加一個(gè)新值MAYBE并僅編譯該枚舉Java文件 ,然后使用字符串“ MAYBE”運(yùn)行GrowingEnumSwitchDemo.main(String[]) , GrowingEnumSwitchDemo.main(String[])遇到IncompatibleClassChangeError 。 接下來(lái)顯示新的Response.java清單,然后是屏幕快照,該屏幕快照演示了僅用新值重新編譯枚舉并使用先前編譯的調(diào)用代碼運(yùn)行后,剛剛描述的問(wèn)題。
package dustin.examples.jdk12.switchexp;/*** Enum representation of a response.*/ public enum Response {YES,NO,MAYBE; }
IncompatibleClassChangeError的存在使我們很明顯地發(fā)現(xiàn),枚舉上有一個(gè)新值,該值以前沒(méi)有由switch表達(dá)式處理。 這使開(kāi)發(fā)人員可以通過(guò)添加枚舉值的case或添加全包式default來(lái)修復(fù)switch表達(dá)式。 這可能會(huì)比今天的當(dāng)前情況更好,在當(dāng)前情況下,使用: / break語(yǔ)法的switch語(yǔ)句將在相同情況下無(wú)提示地繼續(xù)運(yùn)行(在先前的代碼清單和屏幕快照中也得到了證明)。
關(guān)于通過(guò)JEP 325引入Java的增強(qiáng)功能,有幾件令人喜歡的事情。“箭頭”語(yǔ)法使switch 表達(dá)式和switch 語(yǔ)句不必承受令人驚訝的范圍問(wèn)題,無(wú)意跌倒的風(fēng)險(xiǎn)或需要明確的break s的負(fù)擔(dān)。 此外,必須返回值的switch 表達(dá)式可以與枚舉結(jié)合使用,以確保所有枚舉值始終在編譯時(shí)進(jìn)行處理(如果并非在編譯時(shí)處理所有枚舉值,則不會(huì)進(jìn)行編譯)如果使用的枚舉添加了一個(gè)值并與先前編譯的客戶(hù)端代碼一起使用,則會(huì)引發(fā)錯(cuò)誤。
翻譯自: https://www.javacodegeeks.com/2018/09/jdk-12-switch-expression-encountering-unanticipated-enum-value.html
jdk switch 枚舉
總結(jié)
以上是生活随笔為你收集整理的jdk switch 枚举_JDK 12开关表达式遇到意外的枚举值的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: spring boot分层_只需5分钟即
- 下一篇: 华为客服人工电话(华为人工电话)