014-Java switch case 语句

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,程序会继续执行后续的分支代码,直到遇到 breakswitch 结束。

示例:演示穿透
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 3default

正确写法:加入 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
好处
  1. 简化语法,不需要 break
  2. 减少冗余代码。

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 表达式的类型必须是以下之一:
    • byte, short, int, char(以及它们的包装类)
    • 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 支持的数据类型byte, short, int, char, String, 枚举类型(enum)等。
breakdefaultbreak 用于防止穿透,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 switchif...else 的性能对比

  • 性能
    • 对于少量条件,switchif...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 分支以 breakreturn 结束,或者使用 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 最佳实践

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小宝哥Code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值