作者:Pallavi Sonal,Light & Wonder 软件工程经理
像大多数 Java 程序员一样,我仍在使用 Java 8!在日复一日的工作中,我对 Java 的热爱被深深埋藏,直到今年初在温暖的冬日阳光下喝着热茶时,我决定重新点燃这份热情,开始了解 Java 9 到 Java 19 中的一些有趣的新特性。
本文以及接下来的系列文章,旨在分享我所发现的一些新特性。这篇文章将介绍我们经典的“switch”语句在 Java 14 中的进化。这里使用的所有示例都可以在我的 GitHub 存储库中找到。
“switch”更改的提案从 JDK 12 开始作为预览功能引入,经过 JDK 13 的改进后再次作为预览功能引入,最终在 JDK 14 中成为一个完全成熟的永久性特性。
下面是我们如何使用“switch”语句的方式:
上面的示例旨在演示经典“switch”的“fall through”语义。前几个“case”语句在冒号之后没有要执行的内容,所以执行会一直落入下一个和下一个,直到遇到“break”。这样看起来很嘈杂,重复的内容也很多。如果我们在“DECEMBER”块中不小心错过了“break”语句,会造成输出结果的混乱,无法确定这个月是 31 天还是 30 天。
下面是从 Java 14 开始的更简洁的写法:
现在看起来好多了!每个“case”标签都允许有多个常量,并且必须用逗号分隔。你可能会说:“嘿!这仍然有‘fall through’,我们仍然可能错过‘break’,在调试时会造成不必要的麻烦。”所以,这里出现了我们在 JDK 8 中都很熟悉的“lambda箭头”,我可以这样编写上面的代码:
现在好多了吧?“case <label> ->”只有当标签匹配时,才会执行“->”右侧的语句或表达式,不会有“fall through”。不用担心错过“break”和意外的“fall through”!如果我们在“case”分支中有多个语句,可以创建一个代码块{}。这意味着,如果我们想在分支中引入一个局部变量,其作用域将仅限于该分支。而在我们经典的“switch”中,局部变量的作用域是整个“switch”块。
现在我们已经过了一半,我将揭示本文标题中奇怪的创意的原因。使用 JDK 14,“switch”语句也可以用作表达式。当我提到lambda箭头时,你可能已经猜到了这一点。这个“->”基本上告诉编译器,“switch”表达式返回一个值,一种隐式的“return”。这就是为什么执行会跳出“switch”,没有必要使用“break”语句的原因。因此,上面的代码可以修改为:
如果“case <label> ->”右侧的表达式是一个完整的块并返回一个值,则被称为“yielding a value”,可以使用下面代码中使用的新的“yield”语句来表示:
使用“switch”作为表达式并不需要使用lambda箭头;相反,也可以使用传统的冒号作为表达式,并使用“yield”语句生成一个值。无论是使用“break”退出“switch”还是使用“yield”,都可以告诉我们它是一个“switch”语句还是一个“switch”表达式。“yield”不是关键字,而是受限标识符,这意味着我们不应该创建一个名为“yield”的类,并在使用方法或变量名称时要小心,以免与“yield”语句产生歧义。
使用“switch”作为表达式的一个非常重要的要求是完备性。这意味着对于“switch”变量的每个可能值,都应该有一个“case”标签。通常可以通过使用“default”子句来处理。当我们使用“enum”时,“switch”表达式覆盖“enum”的所有常量时,显式的“default”子句是不必要的。编译器还会确保对于“switch”表达式,每个“case”分支都会生成一个值或抛出异常。
所有这些对“switch”的更改都是为了更多的变化做准备。**“模式匹配”**仍然是预览功能之一,当涉及到“switch”表达式时,这是一个值得期待的变化。那么,JDK中的这些“switch”更改是让你感到喜悦还是担忧?请在评论中发表你的看法。
本博客文章中表达的观点仅代表作者个人观点,不代表Light & Wonder或其员工的观点或看法。
评论(0)