1. 经典 switch 语句:传统用法
  2. String 类型的 switch
  3. 枚举类型的 switch
  4. 现代 switch:箭头语法与表达式(Java 14+)
  5. switch 表达式 vs switch 语句:何时用哪种?
  6. 常见陷阱与最佳实践
  7. 完整综合示例

在 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)。

  • 来跳出,否则会发生“穿透”(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 语句:何时用哪种?

    特性

    switch 语句(冒号+break)

    switch 表达式(箭头或yield)

    有无返回值

    无(只能赋值给外部变量)

    可以有返回值(直接赋值或使用)

    穿透风险

    容易忘记 break 导致 bug

    箭头语法自动避免,yield 需显式

    代码简洁度

    较冗长

    更紧凑

    适用场景

    只执行动作,不需要结果

    需要计算结果或映射

    建议:在新项目或 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
    正在启动...
    结果: 启动成功


  • 经典 switch:适用于简单匹配,注意
  • break

    和穿透。

  • 和穿透。
  • 字符串 switch:Java 7 后支持,注意 null 和大小写。
  • 枚举 switch:代码漂亮,配合枚举更语义化。
  • 现代 switch 表达式:Java 14+ 推荐,箭头语法 +
  • yield

    返回值,简洁安全。

  • 返回值,简洁安全。
  • 多值匹配:逗号分隔,减少重复代码。
  • 掌握好

    switch

    的进化史,可以让你的 Java 代码既干净又高效,希望本文的众多用法举例能帮助你灵活运用这一强大的分支控制结构。

    的进化史,可以让你的 Java 代码既干净又高效,希望本文的众多用法举例能帮助你灵活运用这一强大的分支控制结构。

    深入浅出 Java Switch,从经典到现代,用法全解析-switch游戏下载社区