
在 2025 年 9 月发布的 TIOBE 榜单上,Java 位居第四,排在 Python、C++和 C 之后。作为一门步入而立之年的语言,Java 一直没有停下现代化改造的脚步,switch 结构的演进就是一例。
在 Java 8 之前,switch 结构只有 switch 语句,只能使用冒号语法(:),相对来说并不复杂。但是从 Java 14 正式引入 switch 表达式和箭头语法(->)、Java 21 正式引入模式匹配之后,switch 结构的复杂性飙升,可能令人感到无所适从。
如果细分的话,那么目前存在 8 种形式的 switch 结构:
switch 语句(无模式匹配+冒号语法)
switch 语句(无模式匹配+箭头语法)
switch 语句(模式匹配+冒号语法)
switch 语句(模式匹配+箭头语法)
switch 表达式(无模式匹配+冒号语法)
switch 表达式(无模式匹配+箭头语法)
switch 表达式(模式匹配+冒号语法)
switch 表达式(模式匹配+箭头语法)
本文以 Java 21(LTS 版本)为基础,主要从语法层面系统梳理一下 switch 结构,为开发者做个参考。
注意,文中提到的“switch 结构”是 switch 语句和 switch 表达式的统称,讨论过程中会视情况区分二者。
前奏:代码不够简洁,意图不够清晰
对于传统的 switch 结构(指不采用模式匹配、使用冒号语法的 switch 语句),想必开发者不会感到陌生:
这样的 switch 结构显然称不上完美:
由于没有返回值,因此不能作为表达式使用,也不能赋给变量;由于冒号语法默认具有穿透性,因此忘记使用 break 语句跳出可能导致逻辑错误,从而影响安全性;由于选择器表达式支持的类型有限,因此 case 标签只能匹配简单的常量值;由于不支持空值检查,因此判断选择器表达式是否为 null 的操作只能放在 switch 结构外部进行。
此外,传统的 switch 结构无法实现类型检查和转换,只能借助烦琐的 instanceof 和强制类型转换:
正是因为代码不够简洁,意图也不够清晰,所以 Java 社区一直存在改进 switch 结构的呼声。
插曲:怎样区分 switch 语句和 switch 表达式
许多人经常会问:对于一个 switch 结构,如何判断它是 switch 语句还是 switch 表达式?
先说结论:观察是否有返回值。
这是因为 switch 语句属于控制流程结构,本身不会产生值;而 switch 表达式属于求值结构,始终会返回值。
有返回值意味着 switch 表达式不仅可以赋给变量,而且可以用作方法返回值或方法参数。相反,由于 switch 语句没有返回值,因此无法赋给变量,也不能作为方法的返回值或方法参数。
当然,switch 语句内部可以使用 return 语句,只不过它的作用是结束方法并返回结果,而不是指 switch 语句本身会返回值。
如下所示,这段代码包括一个 switch 语句和三个 switch 表达式。
可以看到,switch 语句没有使用 default 分支,而三个 switch 表达式都使用了 default 分支。这是因为 switch 语句不必强制满足穷尽性要求,switch 表达式则必须满足穷尽性要求,后面会讨论穷尽性。
此外,switch 语句、赋给变量的 switch 表达式、作为方法返回值的 switch 表达式使用了箭头语法,而作为方法参数的 switch 表达式使用了冒号语法,后面会讨论这两种语法。
一言以蔽之:是否有返回值是区分 switch 语句和 switch 表达式的根本标准。
选择器表达式
选择器表达式决定了 switch 结构的匹配依据,它支持的类型在引入模式匹配前后大相径庭。
引入模式匹配之前
在 Java 诞生之初,选择器表达式只支持 char、byte、short、int 这 4 种基本数据类型及其包装类 Character、Byte、Short、Integer。随着 Java 的发展,Java 5 引入枚举类型,Java 7 开始支持 String。但是很长一段时间以来,无法使用 long、float、double、boolean 及其包装类 Long、Float、Double、Boolean 作为选择器表达式的类型。
为了区分,我们把 char/Character、byte/Byte、short/Short、int/Integer、枚举类型、String 称为传统类型。
引入模式匹配之后
在 Java 21 正式引入模式匹配后,选择器表达式支持的类型大幅扩展,将所有引用类型纳入其中。例如,Object 类、自定义类、数组、接口都属于引用类型,目前都能用于选择器表达式。
由于包装类也属于引用类型,因此现在也可以使用之前无法使用的 Long、Float、Double、Boolean 作为选择器表达式的类型,不过仍然不能使用 long、float、double、boolean。
举例来说,在以下 switch 语句中,选择器表达式的类型是自定义类 Employee。
当然,如果 switch 结构不采用模式匹配,那么选择器表达式的类型依然只限于传统类型。
虽然使用单一变量作为选择器表达式的情况最常见,但是也可以使用任何合法的表达式,例如以下选择器表达式使用的就是 b + 1:
因此,在检查 case 标签的合法性时,需要考虑数值提升、类型转换、运算符优先级等各种因素。
选择器表达式不支持 long、float、double、boolean 有历史和技术实现方面的考虑,但是 Java 的设计者一直在探索放宽限制的可能性。Java 23、Java 24、Java 25 建议将选择器表达式的类型扩大到全部 8 种基本数据类型,并作为预览特性发布。如果今后能成为正式特性,那么选择器表达式的类型限制将完全放开。
case 标签
根据所匹配的内容,可以把 case 标签分为常量 case 标签和模式 case 标签:常量 case 标签匹配的是常量值,而模式 case 标签匹配的是模式。
常量 case 标签
首先要记住,常量 case 标签必须使用编译时常量表达式。也就是说,常量 case 标签只能匹配字面量、枚举常量、常量变量(声明为 final 而且值在编译阶段就能确定的变量),或是由它们构成的表达式。
下面几个 case 标签都属于常量 case 标签:
case 1000(匹配字面量 1000)
enum Color { RED, GREEN, BLUE }、case BLUE(匹配枚举常量 BLUE)
final String GREETING = "Hello";、case GREETING(匹配 final 变量 GREETING)
我们来看以下代码。为什么 case getCookies()和 case cookies 无法编译呢?
这是因为 getCookies()方法的结果在运行阶段才能确定,因此不是编译时常量表达式,不能用于常量 case 标签;cookies 变量虽然声明为 final,但是它的值取决于 getCookies()方法的结果,因此同样不是编译时常量表达式,同样不能用于常量 case 标签。
又如,case args[1]和 case "abc".toUpperCase()标签都无法编译,原因在于 args[1]
和"abc".toUpperCase()都不是编译时常量表达式。
虽然常量 case 标签可以匹配枚举常量,但是长期以来只能使用枚举常量名。Java 21 放宽了限制,除枚举常量名之外,还可以使用类型限定的枚举常量名。
举例来说,在 Java 21 之前,只能使用 case JUNE 这样的形式;而从 Java 21 开始,case JUNE 和 case Month.JUNE 都是合法的语法。
这种变化有助于提高清晰度。如下所示,goodEnumSwitch()方法传入枚举类型 Coin,选择器表达式 c 是枚举类型,因此可以直接使用枚举常量名 TAILS。而 badEnumSwitch()方法传入接口类型 Currency,选择器表达式 c 是接口类型,因此不能直接使用枚举常量名 TAILS,必须加上枚举类型 Coin.TAILS 才能通过编译。
其次,常量 case 标签的类型必须兼容选择器表达式的类型,而且不能超出后者的取值范围。所谓“兼容”,是指常量 case 标签的类型要么与选择器表达式的类型相同,要么可以隐式转换。
举例来说,final 变量 select 的类型 char 可以隐式转换为 int,所以 case select 标签与选择器表达式 month 的类型相互兼容。
如下所示,在第一个 switch 语句中,b 的类型为 byte,而 1000 的类型为 int,超出了 byte 的取值范围,因此无法编译;在第二个 switch 语句中,b + 1 的类型会自动提升为 int,1000 没有超出 int 的取值范围,因此可以编译。
还要注意的是,两个常量 case 标签的值不能重复:
模式 case 标签
引入模式匹配后,case 标签发生了翻天覆地的变化。所有 case 标签匹配的都是模式,包括常量模式、类型模式、记录模式、null 模式。
在模式匹配的体系中,常量 case 标签“升级”为常量模式 case 标签,同样需要满足以下条件:必须使用编译时常量表达式,必须兼容选择器表达式的类型,而且不能超出后者的取值范围。
为了实现更加精细的控制,类型模式和记录模式还支持加入守卫条件。守卫条件以 when 子句开头,相当于在类型模式和记录模式的基础上添加了额外的条件检查。
因此,Java 21 的模式 case 标签可以细分为以下几类:
常量模式 case 标签(例如 case "abc")
类型模式 case 标签:无守卫条件(例如 case String s)
类型模式 case 标签:有守卫条件(例如 case String s when s.length() > 5)
记录模式 case 标签:无守卫条件(例如 case Point(intx, inty))
记录模式 case 标签:有守卫条件(例如 case Point(int x, int y) when x > y)
null 模式 case 标签(也就是 case null)
以下 switch 语句使用了各种模式 case 标签来匹配不同的情况。
目前,模式 case 标签只能匹配引用类型,不能匹配基本数据类型。换句话说,Java 21 支持使用 case String s 这样的形式,但是 case int i 无法通过编译。
Java 23、Java 24、Java 25 建议将模式 case 标签的匹配范围扩展到基本数据类型,并作为预览特性发布。一旦成为正式特性,无疑会极大增强 switch 结构的灵活性。
模式变量
在模式 case 标签中,模式变量是模式匹配成功时自动声明、初始化并绑定到匹配值的局部变量。以 case String s 为例,s 是模式变量,它的类型是 String。
注意,模式变量的类型要么与选择器表达式的类型相同,要么是其子类型。如下所示,选择器表达式 fish 的类型是 Number,而模式变量 s 的类型是 String,因此编译器会报错。
模式变量属于局部变量,所以其作用域仅限于匹配成功的 case 分支内部。例如,以下三个模式 case 标签定义的模式变量都是 value,但它们的作用域互不重叠,因此变量名不会相互冲突。
case null
在引入模式匹配之前,如果选择器表达式的值为 null,那么运行时会直接抛出 NullPointerException(NPE),这使得判断选择器表达式是否为 null 的操作只能放在 switch 结构外部进行:
Java 的设计者认为,这样处理不仅会产生不必要的样板代码,也会增加出错的概率,更好的方案是将空值检查集成到 switch 结构中,因此在引入模式匹配时专门设计了用于匹配 null 的 case 标签:case null。
也就是说,当采用模式匹配时,如果选择器表达式的值为 null,那么 switch 结构是否抛出 NPE 取决于是否存在 case null 标签:存在则不会抛出 NPE,不存在则仍然会抛出 NPE。
因此,之前的示例可以改写为:
为了保持向后兼容性,default 标签不会匹配 null。换句话说,如果只有 default 标签而没有 case null 标签,那么当选择器表达式的值为 null 时仍然会抛出 NPE。
语法方面有几点需要注意。
1. 如果 switch 结构中既有 case null 标签又有 default 标签,那么 case null 标签必须位于 default 标签之前,否则会导致支配性问题。
2. case null 标签可以与 default 标签合并,但是不能与其他 case 标签合并。例如,case null, default 是合法的语法,而 case null, String s 无法通过编译。
冒号语法和箭头语法
冒号语法从 Java 1.0 起就已存在,而箭头语法是 Java 14 正式引入的特性,属于 Java 现代化改造的一部分。
编写 switch 语句和 switch 表达式时既可以使用冒号语法,也可以使用箭头语法,只是在同一个 switch 结构中不能混用这两种语法。
如下所示,case 9, 10, 11 分支使用了冒号语法,而其他 case 分支和 default 分支使用了箭头语法,因此编译器会报错。
冒号语法和箭头语法的主要区别有两个,一是穿透性,二是返回值的方式。
穿透性
我们知道,Java 在设计之初大量借鉴了 C 和 C++的语法,因此 switch 语句的冒号语法也继承了 C 语言的穿透性。如果希望避免穿透,就要使用 break、return 或 throw 语句来显式跳出分支。
而消除穿透性是箭头语法的设计目的之一。使用箭头语法的分支在执行完毕后,控制流会自动跳出 switch 结构。
注意,当分支的语句组/规则体是单条语句时,不能使用 break 语句,因为箭头语法本身就已阻止穿透;而当分支的语句组/规则体是代码块时,块内可以使用 break 语句,只不过它属于冗余,并不会影响 switch 结构的控制流。
上面提到了“语句组/规则体”,其中语句组指冒号语法后面的内容,规则体指箭头语法后面的内容,稍后会详细讨论。
如下所示,case 1 分支的规则体是代码块,因此是否使用 break 语句均可;其他两个 case 分支和 default 分支的规则体是单条语句,因此不能使用 break 语句。
在引入模式匹配之后,无穿透性成为硬性规定,它也是模式匹配的核心原则之一。
返回值的方式
冒号语法本身没有返回值的功能,箭头语法则自带返回值的功能,记住这一点很重要。
对于使用冒号语法的 switch 表达式来说,无论分支的语句组是单条语句还是代码块,都要通过 yield 语句来返回值。
而对于使用箭头语法的 switch 表达式来说,当分支的规则体是单条语句时,可以直接返回值,不需要也不能使用 yield 语句;当规则体是代码块时,必须通过 yield 语句来返回值。
以下两个 switch 表达式分别使用了冒号语法和箭头语法,不难看出为什么第二个 switch 表达式的 case 1 和 case 2 分支无法编译。
传统的 switch 结构支持多个 case 标签共享相同的代码,标签之间用冒号隔开,例如 case 1: case 2: System.out.print("1 or 2");。我们来看下面这段代码:
这段代码的本意是根据当前日期是星期几来输出对应的消息:周一或周二则输出"MON/TUE",周三、周四、周五则输出"WED - FRI",周六或周日则输出“SAT/SUN”。
假设当前日期是周二(即选择器表达式 dow 的值为 TUESDAY),那么根据代码逻辑应该输出“MON/TUE”,然而实际的输出结果的却是"SAT/SUN"。这是因为 TUESDAY 只是个普通的标签,并不是 case 标签(case TUESDAY 才是)。由于没有匹配到任何 case 标签,因此程序将执行 default 分支。
使用箭头语法改写上述 switch 语句后,就能正确输出当前日期对应的星期几:
注意,改写之前的代码没有编译错误,但是逻辑存在问题。而改用箭头语法后代码变得更简洁,意图也更清晰,还能彻底避免因忘写 break 语句而造成的穿透性错误,所以在现代 Java 开发中建议首选箭头语法。
语句组/规则体
如前所述,switch 结构既能使用冒号语法,也能使用箭头语法。对于这两种语法后面的内容,Java 语言规范给出了标准称谓:当使用冒号语法时,冒号后面的内容称为语句组;当使用箭头语法时,箭头后面的内容称为规则体。
换言之,“语句组”是冒号语法的专用术语,而“规则体”是箭头语法的专用术语。更简单地说,语句组对应冒号语法,规则体对应箭头语法。
使用冒号语法时,语句组可以包含任意数量的语句或代码块,必要时可以抛出异常,也可以为空;而使用箭头语法时,规则体可以包含单个表达式或单个代码块,必要时可以抛出异常,但不能为空。
注意,因为 switch 表达式必须有返回值,所以必须保证任何一条执行路径都能产生结果。
以下 switch 语句和 switch 表达式分别使用了箭头语法和冒号语法,相应的规则体和语句组可以包含各种内容。
插曲:怎样判断 switch 结构有没有采用模式匹配
另一个经常被问到的问题是:对于一个 switch 结构,如何判断它是否采用了模式匹配?
方法很简单:先观察选择器表达式,如有必要再观察 case 标签。
第 1 步 观察选择器表达式。
如果选择器表达式的类型是除传统类型之外的类型(例如 Object 类、自定义类、数组、接口),就说明 switch 结构一定采用了模式匹配,不需要再观察 case 标签。
如果选择器表达式的类型是传统类型(byte/Byte、short/Short、char/Character、int/Integer、枚举类型、String),那么还不能确定 switch 结构有没有采用模式匹配,需要继续观察 case 标签。
第 2 步 观察 case 标签。
如果所有 case 标签都是常量 case 标签(例如 case "abc"),就说明 switch 结构没有采用模式匹配。
如果至少有一个 case 标签是模式 case 标签(例如 case String s),就说明 switch 结构采用了模式匹配。
我们以下面这个 switch 语句为例来解释判断过程。
1. 选择器表达式 value 的类型是 Integer,它是传统类型,还不足以判断上述 switch 语句是否采用了模式匹配,需要继续观察 case 标签。
2. case 1 既可能是常量 case 标签,也可能是常量模式 case 标签,所以仅凭这个 case 标签依然无法判断,需要继续观察其他 case 标签。
3. case Integer i 是类型模式 case 标签,这是类型匹配独有的特征,由此可知 switch 语句一定采用了模式匹配。
4. 由于采用了模式匹配,因此可以断定 case 1 属于常量模式 case 标签。
模式匹配三原则
模式匹配是极其强大的特性,不过为了享受模式匹配给开发带来的便利性,必须遵循三条核心规则:穷尽性、支配性、穿透性。
穷尽性
所谓“穷尽性”,是指编译器会检查 case 标签和 default 标签是否涵盖了选择器表达式所有可能的取值。
对于不采用模式匹配的 switch 语句来说,穷尽性不是硬性规定;而对于采用模式匹配的 switch 语句来说,必须要满足穷尽性要求。
switch 表达式的标准则严格得多:无论是否采用模式匹配,switch 表达式都要满足穷尽性要求,以保证在任何情况下都能返回值。
怎样做到这一点呢?最常见的方案是使用 default 标签来兜底。default 标签可以匹配所有没有被 case 标签涵盖的取值,相当于实现穷尽性的万能钥匙。
当然,只要穷尽性要求得到满足,编译器就不会强制要求使用 default 标签。
举例来说,如果选择器表达式的类型是枚举类型,并且 case 标签已经涵盖了所有枚举常量,那么是否使用 default 标签均可。
类似地,如果选择器表达式的类型是密封类或密封接口,并且 case 标签已经涵盖了密封类的所有子类或密封接口的所有子类型,那么也不需要再使用 default 标签。
如下所示,选择器表达式的类型是 Shape,这个密封接口有且仅有两个子类型 Circle 和 Rectangle,而 case Circle c 和 case Rectangle r 标签已经涵盖了这两个子类型,因此不需要再使用 default 标签。
再来看一个示例。以下 switch 语句能否编译呢?
答案是否定的。
选择器表达式 visitor 的类型为 Number,它包括 Integer、Double、Long、BigDecimal 等多个子类;而 case Integer count 标签只能匹配 Integer 的取值,并没有处理非 Integer 的情况,因此不满足穷尽性要求。
有几种修复方案。一是将选择器表达式和模式变量改为相同的类型,也就是将 visitor 的类型从 Number 改为 Integer,或是将 count 的类型从 Integer 改为 Number。
二是在末尾增加匹配 Number 的 case 标签,例如:
三是在末尾增加 default 标签作为兜底,例如:
当穷尽性要求已经得到满足时,是否还使用 default 标签是个见仁见智的问题。建议不要仅仅为了兜底而添加 default 标签,因为明确列出所有已知情况,往往比一个笼统的 default 标签更能体现代码意图。
支配性
所谓“支配性”,是指更具体(匹配范围更窄)的模式 case 标签必须位于更通用(匹配范围更宽)的模式 case 标签之前,否则会被后者“遮蔽”而导致不可达错误。
之所以设计支配性规则,是为了防止出现永远匹配不到的模式 case 标签。
我们梳理一下模式匹配的支配性规则。
规则 1 子类优先于父类。
换句话说,匹配子类的模式 case 标签必须位于匹配父类的模式 case 标签之前。
以 case Object o 和 case Number n 为例。Object 可以匹配任何引用类型,而 Number 只能匹配 Number 及其子类(例如 Integer 和 Double)。如果 case Object o 出现在 case Number n 之前,那么所有 Number 及其子类的取值在匹配过程中都会先被 Object o 捕获,从而导致 case Number n 不可达。
规则 2 常量模式优先于类型模式,有守卫条件优先于无守卫条件。
换句话说,常量模式 case 标签必须位于有守卫条件的模式 case 标签之前,有守卫条件的模式 case 标签必须位于无守卫条件的模式 case 标签之前。
如下所示,由于违反了这条规则,因此 case -1, 1 无法编译。
注意,只有当守卫条件使用编译时常量表达式时,编译器才会进行支配性检查。我们来看下面这段代码:
两个 case 标签都使用了守卫条件,第一个守卫条件 i > 0 看似会支配第二个守卫条件 i == 1,但这段代码其实可以编译通过,程序将执行第一个 case 分支并输出“Positive value”。
原因在于,i > 0 和 i == 1 都不是编译时常量表达式,因此不涉及支配性检查。虽然第二个 case 标签确实不会执行,但是编译器并不会因此而报错。
如果同一个 switch 块中既使用无守卫条件的模式 case 标签,又使用有守卫条件的模式 case 标签,那么顺序很重要:对于同一类型的模式 case 标签,需要做到有守卫条件的在前,无守卫条件的在后,否则会出现支配性问题;不同类型的模式 case 标签则没有顺序方面的要求。
如下所示,case Integer i 和 case Integer i when i > 10 的类型是 Integer,case Double num 和 case Double num when num <= 15.5 的类型是 Double。根据支配性规则,case Integer i when i > 10 必须位于 case Integer i 之前,case Double num when num <= 15.5 必须位于 case Double num 之前;case Integer i 和 case Integer i when i > 10 位于 case Double num 和 case Double num when num <= 15.5 之前或之后都可以。当然,case Number num 一定要位于最后。
规则 3 如果守卫条件恒为 true,那么有守卫条件的模式 case 标签相当于无守卫条件的模式 case 标签。
我们来看下面这段代码:
A 和 B 都是常量变量,所以守卫条件 A < B 属于编译时常量表达式,这意味着编译器会进行支配性检查。
由于 A 的值为 10,B 的值为 20,因此 A < B 的结果必然为 true,这一点在编译阶段就可以确定。换句话说,编译器将 case String s when A < B 当作 case String s 来处理。而这样一来,就相当于 case String s 位于 case String s when s.length() == 0 之前,显然违反了支配性规则。
规则 4 不能存在多个可以匹配所有取值的标签。
换句话说,switch 结构中只能有一个兜底标签,要么是 default 标签,要么是可以无条件匹配选择器表达式的 case 标签。
这一点很好理解:如果存在多个兜底标签,那么肯定会导致不可达错误。
如下所示,选择器表达式 s 的类型是 String,而 case String t 能够匹配 String 的所有非 null 取值,因此会与 default 标签发生冲突,导致 default 标签永远不可达。
下面这段代码无法编译的原因类似:switch 语句中存在两个兜底标签。
题外话:try/catch 结构也要遵循支配性规则
如果 try/catch 结构使用了多个捕获异常的 catch 子句,而且这些异常之间存在继承关系,那么子类异常(更具体的异常)必须在前,父类异常(更通用的异常)必须在后。
换句话说,捕获子类异常的 catch 子句必须位于捕获父类异常的 catch 子句之前,否则捕获子类异常的 catch 子句永远无法执行。
如下所示,两个 catch 子句捕获的异常分别是 RuntimeException 和 ArithmeticException。由于 RuntimeException 是 ArithmeticException 的父类,因此第一个 catch 子句会支配第二个 catch 子句。
穿透性
由于冒号语法有穿透性,而箭头语法没有穿透性,因此关于穿透性的讨论主要针对冒号语法。
模式匹配对穿透性的要求十分严格:无论是 switch 语句还是 switch 表达式,只要采用模式匹配,就必须保证无穿透性。
对于采用模式匹配的 switch 语句来说,各个 case 分支需要通过 break、return 或 throw 语句跳出以避免穿透,如下所示。
break 和 return 语句的区别在于,前者的作用是跳出 switch 语句,而后者的作用是跳出整个方法。
我们来看以下代码:case Integer i 分支使用 break 语句跳出 switch 语句,控制流返回到 demo()方法的末尾;demo()方法要求所有可能的执行路径返回 String,而 case Integer i 分支并没有返回值,因此编译器会报错。
我们知道,switch 表达式必须有明确的结果。为了保证无穿透性,switch 表达式要么通过 yield 语句产生值,要么通过 throw 语句抛出异常,但是不能使用 return 语句。
尾声:代码更加简洁,意图更加清晰
自从引入 switch 表达式、箭头语法、模式匹配等特性之后,switch 结构变得极其灵活,但是学习成本也显著增加。对于习惯使用传统 switch 结构的开发者来说,可能需要一段时间来熟悉新的特性。
当决策逻辑比较简单,或者只需要进行基于整型或枚举的常量匹配时,传统的 switch 结构仍然适用。而对于本文开头提到的类型检查和转换,经过现代化改造的 switch 结构无疑更简洁也更清晰:
模式匹配是 Java 现代化改造的关键一环,也是最重要的特性之一。它不仅扩展了选择器表达式支持的类型,而且增强了类型安全性,还在一定程度上减少了样板代码。虽然部分开发者依然坚持“你发任你发,我用 Java 8”,但是在条件允许的情况下,建议新项目优先考虑使用经过现代化改造的 switch 结构。
作者简介:
蒋楠,出身电子与计算机工程专业的高级技术产品经理,负责 C 端产品的规划和设计,对算法和数据密集型应用同样兴趣浓厚。兼具科技图书译者、马拉松跑者、航天爱好者等多重身份,译作包括《计算机简史》《计算机科学精粹》等。
评论