Java switch case语句的用法及常见问题

 更新时间:2025年04月25日 08:42:49   作者:小宝哥Code  
这篇文章主要介绍了Java switch case语句的用法及常见问题,Java中的switch语句是一种多分支选择结构,用于替代多个if...elseif的情况,它根据某个变量的值,执行匹配分支中的代码块,文中通过代码介绍的非常详细,需要的朋友可以参考下

switch 语句是 Java 中一种多分支选择结构,用于替代多个 if...else if 的情况。它根据某个变量的值,执行匹配分支中的代码块。

1. 基本语法

switch (表达式) {
    case 值1:
        // 当表达式的值等于 值1 时执行的代码
        break; // 可选,跳出 switch 语句
    case 值2:
        // 当表达式的值等于 值2 时执行的代码
        break;
    ...
    default:
        // 当所有 case 都不匹配时执行的代码
        break; // 可选
}
  • 表达式:可以是 byteshortintcharString 或枚举类型(enum)。
  • case:每个分支的值必须是常量,且值类型必须与表达式的类型一致。
  • break:用于跳出 switch 语句。若省略 break,程序会继续执行下一个 case(称为switch 穿透)。
  • default:可选,处理所有不匹配的情况,类似 else

2. 示例代码

2.1 简单的 switch 示例

public class Main {
    public static void main(String[] args) {
        int day = 3;
        switch (day) {
            case 1:
                System.out.println("Monday");
                break;
            case 2:
                System.out.println("Tuesday");
                break;
            case 3:
                System.out.println("Wednesday");
                break;
            case 4:
                System.out.println("Thursday");
                break;
            case 5:
                System.out.println("Friday");
                break;
            default:
                System.out.println("Weekend");
        }
    }
}

输出

Wednesday

2.2 使用 String 类型的 switch

从 Java 7 开始,switch 支持 String 类型。

public class Main {
    public static void main(String[] args) {
        String color = "Red";
        switch (color) {
            case "Red":
                System.out.println("Stop!");
                break;
            case "Yellow":
                System.out.println("Caution!");
                break;
            case "Green":
                System.out.println("Go!");
                break;
            default:
                System.out.println("Invalid color.");
        }
    }
}

输出

Stop!

2.3 使用枚举类型的 switch

switch 可以和 enum 类型结合使用,这在处理固定集合的值时非常有用。

public class Main {
    public enum Day {
        MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
    }

    public static void main(String[] args) {
        Day today = Day.FRIDAY;

        switch (today) {
            case MONDAY:
                System.out.println("Start of the week.");
                break;
            case FRIDAY:
                System.out.println("End of the work week.");
                break;
            case SATURDAY:
            case SUNDAY:
                System.out.println("It's the weekend!");
                break;
            default:
                System.out.println("Midweek day.");
        }
    }
}

输出

End of the work week.

2.4 多个 case 合并

多个 case 分支可以合并处理,避免重复代码。

public class Main {
    public static void main(String[] args) {
        int month = 7;

        switch (month) {
            case 12:
            case 1:
            case 2:
                System.out.println("Winter");
                break;
            case 3:
            case 4:
            case 5:
                System.out.println("Spring");
                break;
            case 6:
            case 7:
            case 8:
                System.out.println("Summer");
                break;
            case 9:
            case 10:
            case 11:
                System.out.println("Autumn");
                break;
            default:
                System.out.println("Invalid month");
        }
    }
}

输出

Summer

3. switch 穿透现象

如果分支中没有 break,程序会继续执行后续的分支代码,直到遇到 break 或 switch 结束。

示例:演示穿透

public class Main {
    public static void main(String[] args) {
        int number = 2;

        switch (number) {
            case 1:
                System.out.println("One");
            case 2:
                System.out.println("Two");
            case 3:
                System.out.println("Three");
            default:
                System.out.println("Default");
        }
    }
}

输出

Two
Three
Default

分析

  • number 等于 2,匹配到 case 2,执行其代码。
  • 因为没有 break,继续执行 case 3 和 default

正确写法:加入 break

public class Main {
    public static void main(String[] args) {
        int number = 2;

        switch (number) {
            case 1:
                System.out.println("One");
                break;
            case 2:
                System.out.println("Two");
                break;
            case 3:
                System.out.println("Three");
                break;
            default:
                System.out.println("Default");
        }
    }
}

输出

Two

4. switch 的进阶用法

4.1 switch 表达式(Java 12+)

从 Java 12 开始,switch 可以作为表达式使用,返回一个值。

语法

int result = switch (表达式) {
    case 值1 -> 值1的结果;
    case 值2 -> 值2的结果;
    default -> 默认结果;
};

示例:返回值

public class Main {
    public static void main(String[] args) {
        int day = 5;
        String result = switch (day) {
            case 1 -> "Monday";
            case 2 -> "Tuesday";
            case 3 -> "Wednesday";
            case 4 -> "Thursday";
            case 5 -> "Friday";
            case 6, 7 -> "Weekend";
            default -> "Invalid day";
        };
        System.out.println(result);
    }
}

输出

Friday

好处:

  • 简化语法,不需要 break
  • 减少冗余代码。

4.2 多行代码块(Java 13+)

在 Java 13 中,switch 表达式支持多行代码块。

示例:多行代码块

public class Main {
    public static void main(String[] args) {
        int day = 5;

        String result = switch (day) {
            case 1 -> "Monday";
            case 2 -> "Tuesday";
            case 5 -> {
                System.out.println("More logic for Friday...");
                yield "Friday"; // 使用 yield 返回值
            }
            default -> "Invalid day";
        };
        System.out.println(result);
    }
}

输出

More logic for Friday...
Friday

5. 常见问题与注意事项

5.1 忘记 break

  • switch 分支中忘记添加 break 会导致穿透现象。
  • 如果不需要穿透,务必在每个 case 分支后添加 break

5.2 default 的位置

  • default 可以出现在 switch 的任何位置,但通常写在最后,增强可读性。

5.3 表达式类型的限制

  • switch 表达式的类型必须是以下之一:
    • byteshortintchar(以及它们的包装类)
    • String
    • 枚举类型(enum

5.4 处理 NullPointerException

如果 switch 表达式为 null 且类型为 String,会抛出 NullPointerException

错误示例

public class Main {
    public static void main(String[] args) {
        String color = null;

        switch (color) { // 会抛出 NullPointerException
            case "Red":
                System.out.println("Stop");
                break;
            default:
                System.out.println("Invalid color");
        }
    }
}

解决方法

在使用 switch 之前,先检查是否为 null

if (color == null) {
    System.out.println("Invalid color");
} else {
    switch (color) {
        case "Red":
            System.out.println("Stop");
            break;
        default:
            System.out.println("Invalid color");
    }
}

6. 总结

特性描述
switch 支持的数据类型byteshortintcharString, 枚举类型(enum)等。
break 和 defaultbreak 用于防止穿透,default 用于处理所有不匹配的情况。
switch 表达式(Java 12+)简化语法,直接返回值,无需 break,更清晰且简洁。
多行代码块(Java 13+)使用 yield 返回值,支持多行逻辑处理。
适用场景多值匹配、值相等判断(如菜单选项、枚举状态、字符串匹配等)。

通过合理使用 switch 语句,可以让代码逻辑更清晰、更高效,尤其是在处理多分支选择时,是一种非常直观的解决方案!

我们已经详细探讨了 Java 中 switch case 语句的基础知识、进阶用法和优化技巧。在接下来的部分,我们将进一步探讨 switch 的高级特性、性能优化、常见问题的解决方案 以及 实践中的应用场景,帮助你更全面地掌握 switch 语句并在实际开发中高效使用。

7. switch 的高级特性

7.1 switch 和多值匹配

从 Java 12 开始,switch 表达式支持多值匹配,这大大简化了多个 case 之间的逻辑。

示例:多个 case 匹配相同逻辑

public class Main {
    public static void main(String[] args) {
        int day = 6;

        String result = switch (day) {
            case 1, 2, 3, 4, 5 -> "Weekday";
            case 6, 7 -> "Weekend";
            default -> "Invalid day";
        };

        System.out.println(result);
    }
}

输出

Weekend

好处

  • 使用逗号分隔多个 case 值,减少代码冗余。
  • 更清晰地表达多个值对应相同逻辑的意图。

7.2 yield 的使用

在 Java 13 中,switch 表达式引入了 yield 关键字,用于返回计算结果。它可以支持多行的逻辑处理,并返回一个值。

多行逻辑的 yield 示例

public class Main {
    public static void main(String[] args) {
        int number = 2;

        String result = switch (number) {
            case 1 -> "One";
            case 2 -> {
                System.out.println("Processing case 2...");
                yield "Two"; // 返回值
            }
            case 3 -> "Three";
            default -> "Unknown";
        };

        System.out.println("Result: " + result);
    }
}

输出

Processing case 2...
Result: Two

分析

  • yield 替代了 return,用于 switch 表达式中返回值。
  • 支持多行代码逻辑,增强了可读性和灵活性。

7.3 switch 的嵌套

在一些复杂场景中,可以使用嵌套的 switch 语句来处理多层逻辑。

示例:嵌套 switch 实现多条件判断

public class Main {
    public static void main(String[] args) {
        String role = "Manager";
        String department = "HR";

        switch (role) {
            case "Manager":
                switch (department) {
                    case "HR":
                        System.out.println("HR Manager");
                        break;
                    case "IT":
                        System.out.println("IT Manager");
                        break;
                    default:
                        System.out.println("General Manager");
                }
                break;
            case "Employee":
                System.out.println("Employee");
                break;
            default:
                System.out.println("Unknown role");
        }
    }
}

输出

HR Manager

7.4 使用 switch 处理复杂逻辑

switch 常用于处理预定义的条件、菜单选项、状态处理等场景。结合方法和枚举,可以进一步提高可读性和灵活性。

示例:结合枚举和方法处理状态

public class Main {
    public enum OrderStatus {
        PENDING, PROCESSING, COMPLETED, CANCELED
    }

    public static void main(String[] args) {
        OrderStatus status = OrderStatus.PROCESSING;

        String message = processOrderStatus(status);
        System.out.println(message);
    }

    public static String processOrderStatus(OrderStatus status) {
        return switch (status) {
            case PENDING -> "Your order is pending.";
            case PROCESSING -> "Your order is being processed.";
            case COMPLETED -> "Your order has been completed.";
            case CANCELED -> "Your order has been canceled.";
        };
    }
}

输出

Your order is being processed.

8. 性能优化与注意事项

8.1 switch 与 if...else 的性能对比

  • 性能
    • 对于少量条件,switch 和 if...else 性能相差不大。
    • 对于大量条件,switch 通常比 if...else 更高效,因为编译器会优化 switch 为跳转表(jump table)或二分查找(binary search)。
  • 可读性
    • switch 更适合处理固定值的分支选择。
    • if...else 更适合处理复杂的布尔表达式或区间判断。

示例:区间判断更适合使用 if...else

public class Main {
    public static void main(String[] args) {
        int score = 85;

        if (score >= 90) {
            System.out.println("Grade: A");
        } else if (score >= 80) {
            System.out.println("Grade: B");
        } else if (score >= 70) {
            System.out.println("Grade: C");
        } else {
            System.out.println("Grade: F");
        }
    }
}

8.2 避免穿透现象(无意的 fall-through)

  • 未添加 break 会导致意外的穿透现象,执行后续的 case 代码。
  • 解决方法:确保每个 case 分支以 break 或 return 结束,或者使用 switch 表达式(Java 12+),该表达式默认不会穿透。

8.3 default 的使用

  • 建议:始终提供 default 分支,即使你认为所有可能的值都已涵盖。
  • 作用:处理意外值,避免程序出现逻辑漏洞。

8.4 避免 null 值引发问题

  • switch 不支持直接匹配 null 值,若传入 null,会抛出 NullPointerException
  • 解决方案:在使用 switch 前先检查是否为 null

9. 实际开发中的应用场景

9.1 菜单系统

示例:简单菜单系统

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("Menu:");
        System.out.println("1. Start Game");
        System.out.println("2. Load Game");
        System.out.println("3. Exit");
        System.out.print("Enter your choice: ");

        int choice = scanner.nextInt();
        switch (choice) {
            case 1 -> System.out.println("Game Started!");
            case 2 -> System.out.println("Game Loaded!");
            case 3 -> System.out.println("Exiting...");
            default -> System.out.println("Invalid choice!");
        }
    }
}

9.2 状态机

switch 非常适合实现状态机,用于根据当前状态执行不同的操作。

示例:简单状态机

public class Main {
    public enum Light {
        RED, YELLOW, GREEN
    }

    public static void main(String[] args) {
        Light current = Light.RED;

        switch (current) {
            case RED -> System.out.println("Stop!");
            case YELLOW -> System.out.println("Ready!");
            case GREEN -> System.out.println("Go!");
        }
    }
}

9.3 错误代码处理

switch 可以用于根据错误代码返回对应的错误信息。

示例:根据错误代码提示信息

public class Main {
    public static void main(String[] args) {
        int errorCode = 404;

        String message = switch (errorCode) {
            case 200 -> "OK";
            case 400 -> "Bad Request";
            case 404 -> "Not Found";
            case 500 -> "Internal Server Error";
            default -> "Unknown Error";
        };

        System.out.println("Error: " + message);
    }
}

10. 总结与建议

10.1 适用场景

场景推荐结构
固定值的多分支选择使用 switch
区间判断或复杂布尔逻辑使用 if...else
需要返回值的选择结构使用 switch 表达式(Java 12+)

10.2 最佳实践

  • 选择合适的结构:对于固定值的分支,优先使用 switch,尤其是枚举和字符串匹配。
  • 避免穿透现象:确保每个 case 使用 break 或 return 结束。
  • 总是提供 default:处理意外情况,增强代码的鲁棒性。
  • 使用 switch 表达式:在 Java 12+ 中,推荐使用 switch 表达式简化代码逻辑。
  • 提前处理 null 值:避免因 null 引发 NullPointerException

通过合理使用 switch case 语句,不仅可以提升代码的可读性和效率,还能更好地应对多条件分支的复杂场景!

总结

到此这篇关于Java switch case语句的用法及常见问题的文章就介绍到这了,更多相关Java switch case语句用法内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • mybatis-plus中的常用注解

    mybatis-plus中的常用注解

    这篇文章主要介绍了mybatis-plus中的常用注解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Spring boot实现文件上传功能

    Spring boot实现文件上传功能

    这篇文章主要为大家详细介绍了Spring boot实现文件上传功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • RocketMQ事务消息原理与使用详解

    RocketMQ事务消息原理与使用详解

    RocketMQ事务消息(Transactional Message)是指应用本地事务和发送消息操作可以被定义到全局事务中,要么同时成功,要么同时失败。RocketMQ的事务消息提供类似 X/Open XA 的分布式事务功能,通过事务消息能达到分布式事务的最终一致
    2023-02-02
  • 深入了解JAVA HASHMAP的死循环

    深入了解JAVA HASHMAP的死循环

    HASHMAP基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)下面小编来带大家详细了解下吧
    2019-06-06
  • 关于自定义过滤器获取不到session问题

    关于自定义过滤器获取不到session问题

    这篇文章主要介绍了关于自定义过滤器获取不到session问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • Java编程调用微信支付功能的方法详解

    Java编程调用微信支付功能的方法详解

    这篇文章主要介绍了Java编程调用微信支付功能的方法,结合实例形式详细分析了java微信支付功能的原理、操作流程及相关实现技巧,需要的朋友可以参考下
    2017-08-08
  • SpringBoot项目在IntelliJ IDEA中如何实现热部署

    SpringBoot项目在IntelliJ IDEA中如何实现热部署

    spring-boot-devtools是一个为开发者服务的一个模块,其中最重要的功能就是自动应用代码更改到最新的App上面去。,这篇文章主要介绍了SpringBoot项目在IntelliJ IDEA中如何实现热部署,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • Java spring mvc请求详情介绍

    Java spring mvc请求详情介绍

    这篇文章主要介绍了Java spring mvc请求详情,mvc是spring源码中的一个子模块,下文关于spring mvc请求的相关资料做简单介绍,需要的小伙伴可以参考一下,希望对你有所帮助
    2022-03-03
  • 一文掌握Java中的JWT

    一文掌握Java中的JWT

    这篇文章主要介绍了Java中的JWT,JWT的本质就是一个字符串,它是将用户信息保存到一个Json字符串中,然后进行编码后得到一个JWT token,对JWT相关知识感兴趣的朋友一起看看吧
    2022-06-06
  • SpringBoot开发存储服务器实现过程详解

    SpringBoot开发存储服务器实现过程详解

    这篇文章主要为大家介绍了SpringBoot开发存储服务器实现过程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12

最新评论