Java 17 更新(7):模式匹配要支持 switch 啦
Java 的 switch 又加强啦!
- Java 17 更新(0):前言
- Java 17 更新(1):更快的 LTS 节奏
- Java 17 更新(2):没什么存在感的 strictfp 这回算是回光返照了
- Java 17 更新(3):随机数生成器来了一波稳稳的增强
- Java 17 更新(4):这波更新,居然利好 mac 用户
- Java 17 更新(5):历史包袱有点儿大,JDK 也在删代码啦
- Java 17 更新(6):制裁!我自己私有的 API 你们怎么随便一个人都想用?
- Java 17 更新(7):模式匹配要支持 switch 啦
- Java 17 更新(8):密封类终于转正
- Java 17 更新(9):Unsafe 不 safe,我们来一套 safe 的 API 访问堆外内存
- Java 17 更新(10):访问外部函数的新 API,JNI 要凉了?
- Java 17 更新(11):支持矢量运算,利好科学计算?
- Java 17 更新(12):支持上下文的序列化过滤器,又一次给序列化打补丁
这一次我们来聊聊 **JEP 406: Pattern Matching for switch (Preview)**。这是一个预览特性。
前面我们提到过 Java 16 引入了一个对于 instanceof 的模式匹配:
1 | // Old code |
这个其实从效果上类似于 Kotlin 的智能类型转换:
1 | if (o is String) { |
不过,模式匹配可以做的事情更多。
Java 17 引入了一个 preview 的特性,可以通过 switch 语句来实现类似的类型模式匹配:
1 | static String formatterPatternSwitch(Object o) { |
对于每一个 case 语句,我们都可以使用类型模式匹配,如果 o 的类型是 Integer,那么它就可以匹配到第一个 case 分支,并且在这个分支内部可以用新变量 i 来替代 o。
请注意,switch 语句在 Java 14 正式支持了表达式,有些朋友可能对这个语法不是很熟悉, 每一个 case 语句后面的 ->
都是一个表达式,并且不会落到下一个 case 分支,所以大家也不会在这里看到 break。不仅如此,switch 表达式的参数 o 的类型也做了放宽,我们在后面介绍密封类的时候还可以看到对这一点的运用。
不仅如此,这次 switch 表达式还添加了对 null 的支持:
1 | static void testFooBar(String s) { |
这样我们就可以把 null 放到第一个分支来实现空检查了,非常方便。
模式匹配在 Java 的近亲 Scala 上得到了广泛的运用,当然 Scala 的模式匹配要复杂得多,下面是我从 Scala 官网摘的例子:
1 | abstract class Notification |
case class 类似于 Java 当中的 record,或者 Kotlin 当中的 data class,我们看到下面的 match 语句当中,case Email(sender, tit le, _)
语句可以直接对待匹配的对象做解构。此外,还可以添加模式守卫(Pattern Guard),例如:
1 | def showImportantNotification(notification: Notification, importantPeopleInfo: Seq[String]): String = { |
注意每一条 case 后面的 if,在匹配的时候,也需要命中 if 后面的表达式。
Java 在后续的发展过程当中也许也存在添加这样的语法的可能性。
Kotlin 在演进的过程中曾经也一度想要把 when 表达式做成模式匹配,不过可能是后面觉得模式匹配的实用价值不高(???),就没有继续做下去。
稍微提一下,如果想要体验预览特性,需要为 Java 编译器和 Java 运行时添加 --enable-preview
参数。
好,关于预览的 switch 模式匹配我们就先介绍这么多。
关于作者
霍丙乾 bennyhuo,Google 开发者专家(Kotlin 方向);《深入理解 Kotlin 协程》 作者(机械工业出版社,2020.6);《深入实践 Kotlin 元编程》 作者(机械工业出版社,2023.8);移动客户端工程师,先后就职于腾讯地图、猿辅导、腾讯视频。
- GitHub:https://github.com/bennyhuo
- 博客:https://www.bennyhuo.com
- bilibili:霍丙乾 bennyhuo
- 微信公众号:霍丙乾 bennyhuo