- 经典 switch 语句:传统用法
- String 类型的 switch
- 枚举类型的 switch
- 现代 switch:箭头语法与表达式(Java 14+)
- switch 表达式 vs switch 语句:何时用哪种?
- 常见陷阱与最佳实践
- 完整综合示例
在 Java 编程中,
switch语句是一种非常实用的分支控制结构,相比冗长的
if-else链,
switch在许多场景下能让代码更简洁、更可读,许多开发者对
switch的认识还停留在“只能匹配整数或枚举”的旧印象中,从 Java 7 开始,
switch已经支持
String类型;Java 14 正式引入了
switch表达式(预览特性在 Java 12/13),带来了箭头语法、返回值以及更安全的控制流。
表达式(预览特性在 Java 12/13),带来了箭头语法、返回值以及更安全的控制流。
本文将带你从基础到进阶,通过大量用法举例,全面掌握 Java 中
switch的方方面面。
的方方面面。
经典 switch 语句:传统用法
基本语法
经典的
switch语句结构如下:对一个变量进行匹配,每个
case后跟一个常量值,执行对应代码块后通常使用
break跳出;如果没有
break,程序会继续向下穿透执行下一个
case,最后可选的
default分支用于处理未匹配的情况。
分支用于处理未匹配的情况。
byte、
short、
char、
int及其包装类,
String(Java 7+),以及枚举(
enum)。
case后通常需要
break来跳出,否则会发生“穿透”(fall-through)。
经典举例:根据数字输出星期几
假设我们有一个整数变量
day表示星期几(1 到 7),想要得到对应的中文名称,使用传统
switch语句,我们为每个数字分配一个
case,并在每个分支中将
dayName赋值为对应的星期名称,最后用
break退出,当
day为 3 时,执行
case 3分支,将
dayName设置为“星期三”,若输入值不在 1 到 7 之间,
default分支会输出“无效的日期”,最终输出结果为“星期三”。
分支会输出“无效的日期”,最终输出结果为“星期三”。
穿透现象与利用
穿透现象指的是当某个
case分支末尾没有
break时,程序会继续执行下一个
case的代码,直到遇到
break或结束,有时可以故意利用穿透来合并多个条件,例如判断一个月份的天数:将 1、3、5、7、8、10、12 月合并为 31 天,4、6、9、11 月合并为 30 天,2 月单独处理,并在内部判断是否为闰年,如果月份是 2 且年份是 2024(闰年),则天数被设为 29,这种写法避免了重复代码,但必须小心确保逻辑正确,否则容易引发错误。
或结束,有时可以故意利用穿透来合并多个条件,例如判断一个月份的天数:将 1、3、5、7、8、10、12 月合并为 31 天,4、6、9、11 月合并为 30 天,2 月单独处理,并在内部判断是否为闰年,如果月份是 2 且年份是 2024(闰年),则天数被设为 29,这种写法避免了重复代码,但必须小心确保逻辑正确,否则容易引发错误。
注意:穿透虽然灵活,但容易造成逻辑错误,如果不主动利用,务必加上
break。
。
String 类型的 switch
从 Java 7 开始,
switch支持
String类型,其底层通过字符串的
hashCode()和
equals()方法进行匹配,我们可以根据水果名称的字符串来输出其中文名:当变量
fruit为
"apple"时,匹配
case "apple"并输出“苹果”;其他水果类似,注意:
switch对字符串的比较是区分大小写的,且变量不能为
null,否则会抛出
NullPointerException,建议在
switch之前先检查字符串是否为空。
之前先检查字符串是否为空。
枚举类型的 switch
枚举是
switch的天然搭档,代码可读性极高,定义一个季节枚举
Season,包含
SPRING、
SUMMER、
AUTUMN、
WINTER四个常量,然后对一个季节变量
s进行
switch匹配:
s是
SUMMER,则输出“夏日炎炎”,注意:在
case后面直接写枚举常量名,不需要写成
Season.SUMMER,否则会导致编译错误。
,否则会导致编译错误。
现代 switch:箭头语法与表达式(Java 14+)
Java 14 正式引入了
switch表达式,它支持箭头语法,并且可以返回一个值,这一改动极大提升了
switch的简洁性和安全性。
的简洁性和安全性。
箭头语法()
箭头后面可以是语句、代码块或表达式,且自动不会穿透(无需
break),将整数
day映射为星期名称,我们可以直接使用
switch表达式,将结果赋值给一个字符串变量,每个
case后跟箭头,箭头右侧为返回值;
default分支同理,当
day为 3 时,返回“星期三”,这种写法简洁且安全,因为每个分支都是独立的。
为 3 时,返回“星期三”,这种写法简洁且安全,因为每个分支都是独立的。
使用
yield返回值
返回值
在传统冒号语法中,
switch本身不能返回值,但在
switch表达式中,如果仍然希望使用冒号语法(例如需要多行逻辑),可以通过
yield关键字返回一个值,根据成绩分数段划分等级:将分数除以 10 取整,然后对每个区间使用
yield返回等级字符串,当分数为 85 时,匹配
case 8,
yield返回“良好”,注意,此时不需要
break,因为
yield会自动终止当前分支。
会自动终止当前分支。
箭头语法 + 代码块 + yield
箭头后面也可以跟代码块,在块内使用
yield返回结果,判断一个数字的奇偶性:当数字为 1 时,先输出“数字是1”,
yield返回“奇数”;为 2 时输出“数字是2”并返回“偶数”,这种写法适用于每个分支需要执行多条语句且需要返回值的场景。
返回“奇数”;为 2 时输出“数字是2”并返回“偶数”,这种写法适用于每个分支需要执行多条语句且需要返回值的场景。
多值匹配(
case L ->中的逗号分隔)
中的逗号分隔)
Java 14 允许在一个
case中匹配多个值,用逗号分隔,判断一个字符是元音还是辅音:将 a、e、i、o、u(以及对应的大写)放在同一个
case中,箭头右侧统一返回“元音”,这种写法比传统穿透合并更清晰,且不会产生意外的穿透效果。
中,箭头右侧统一返回“元音”,这种写法比传统穿透合并更清晰,且不会产生意外的穿透效果。
注意:相比传统穿透写法,多值匹配使得代码更简洁、更安全。
switch 表达式 vs switch 语句:何时用哪种?
建议:在新项目或 Java 14+ 环境中,优先使用
switch表达式,尤其是在需要返回值时。
表达式,尤其是在需要返回值时。
常见陷阱与最佳实践
不要忘记 default
虽然
default不是必须的,但建议始终包含,避免出现未预期的值导致程序静默失败,对于枚举类型,如果已经覆盖所有常量,可能不需要
default,但编译器会提示警告;此时可以显式添加一个抛出异常的
default分支,
default ->throw new IllegalArgumentException(...),以明确处理异常情况。
,以明确处理异常情况。
switch 中的 null 处理
传统
switch对
null会抛出
NullPointerException,现代箭头语法同样如此,在使用之前务必判空,可以先通过三元表达式将
null转换为空字符串,再进行
switch;或者使用
Optional等更优雅的方式处理。
等更优雅的方式处理。
避免过长的 switch 分支
如果一个
switch有十几个分支,建议考虑使用多态、策略模式或
Map替代,以提高代码的可维护性。
替代,以提高代码的可维护性。
完整综合示例
下面是一个模拟“根据用户输入指令执行操作”的示例,综合展示了传统与现代用法的差异,程序首先提示用户输入命令(start/stop/status/quit),然后使用
switch表达式处理命令,输入
"start"时,分支中先打印“正在启动...”,再通过
yield返回“启动成功”;最终输出结果为“结果: 启动成功”,其他命令类似,
default分支返回未知命令提示,这样既完成了操作,又获得了返回值,代码简洁且逻辑清晰。
分支返回未知命令提示,这样既完成了操作,又获得了返回值,代码简洁且逻辑清晰。
输出示例:
请输入命令 (start/stop/status/quit): start
正在启动...
结果: 启动成功
break和穿透。
yield返回值,简洁安全。
掌握好
switch的进化史,可以让你的 Java 代码既干净又高效,希望本文的众多用法举例能帮助你灵活运用这一强大的分支控制结构。
的进化史,可以让你的 Java 代码既干净又高效,希望本文的众多用法举例能帮助你灵活运用这一强大的分支控制结构。

