switch 语句是 Java 中一个多路分支的控制流结构,它根据一个变量的值来决定执行哪个代码块,它提供了一种比 if-else if-else 链条更清晰、更易读的方式来处理多个离散的值。

基本语法
一个基本的 switch 语句结构如下:
switch (expression) {
case value1:
// 当 expression 等于 value1 时,执行这里的代码
break; // 可选,用于跳出 switch 语句
case value2:
// 当 expression 等于 value2 时,执行这里的代码
break; // 可选
case value3:
// 当 expression 等于 value3 时,执行这里的代码
break; // 可选
default:
// expression 不等于任何一个 case 的值,则执行这里的代码
// default 是可选的
break; // 在 default 中,break 也是可选的,但推荐加上
}
工作原理:
switch计算括号中的expression的值。- 程序将这个值与每个
case子句中的value进行比较。 - 如果找到一个匹配的
value,程序就会开始执行该case后面的代码。 - 如果没有找到任何匹配的
value,并且存在default子句,程序就会执行default后面的代码。 break关键字:当执行到一个break语句时,switch语句会立即终止,程序会跳转到switch语句块后面的第一条语句继续执行。如果没有break,程序会继续执行下一个case的代码,这被称为 "fall-through"(贯穿)。
代码示例
示例 1:基本用法(带 break)
这是最常见的用法,每个 case 都是独立的。
public class SwitchExample {
public static void main(String[] args) {
int day = 3;
String dayName;
switch (day) {
case 1:
dayName = "星期一";
break;
case 2:
dayName = "星期二";
break;
case 3:
dayName = "星期三";
break;
case 4:
dayName = "星期四";
break;
case 5:
dayName = "星期五";
break;
case 6:
dayName = "星期六";
break;
case 7:
dayName = "星期日";
break;
default:
dayName = "无效的日期";
break;
}
System.out.println("今天是 " + dayName); // 输出: 今天是 星期三
}
}
示例 2:fall-through(贯穿)特性
如果你省略了 break,代码会“掉落”到下一个 case 中执行,这在某些场景下很有用,比如多个 case 执行相同的操作。

public class SwitchFallThrough {
public static void main(String[] args) {
int score = 85;
char grade;
switch (score / 10) { // 85 / 10 = 8
case 10:
case 9:
grade = 'A';
break;
case 8:
grade = 'B';
break;
case 7:
grade = 'C';
break;
case 6:
grade = 'D';
break;
default:
grade = 'F';
break;
}
System.out.println("成绩等级是: " + grade); // 输出: 成绩等级是: B
}
}
在这个例子中,case 10 和 case 9 都没有 break,所以如果 score / 10 的结果是 9 或 10,代码会继续执行直到遇到 grade = 'A'; 和 break;。
示例 3:使用 default
default 子句是可选的,但强烈推荐使用,它可以处理所有未预料到的输入,避免程序出现意外行为。
public class SwitchDefault {
public static void main(String[] args) {
String fruit = "mango";
switch (fruit) {
case "apple":
System.out.println("选的是苹果");
break;
case "banana":
System.out.println("选的是香蕉");
break;
// 注意这里没有 case "mango"
default:
System.out.println("没有这种水果,或者我们不认识它。");
break;
}
// 输出: 没有这种水果,或者我们不认识它。
}
}
switch 表达式 (Java 14+ 引入)
从 Java 14 开始,switch 不仅可以作为语句,还可以作为表达式,这意味着它可以返回一个值,大大简化了代码。
switch 表达式的特性:
- 有返回值:可以直接赋值给一个变量。
- 无需
break:使用->(箭头) 代替 (冒号),箭头后只能跟一个表达式、throw语句或一个代码块(用花括号 包裹)。->会自动阻止fall-through,因此不需要break。 - 带
yield的代码块:->后面是一个代码块(多行代码),并且需要返回一个值,则使用yield关键字。
示例 4:switch 表达式
public class SwitchExpression {
public static void main(String[] args) {
int day = 3;
String dayName;
// 使用 switch 表达式
dayName = switch (day) {
case 1 -> "星期一";
case 2 -> "星期二";
case 3 -> "星期三";
case 4 -> "星期四";
case 5 -> "星期五";
case 6 -> "星期六";
case 7 -> "星期日";
default -> "无效的日期";
};
System.out.println("今天是 " + dayName); // 输出: 今天是 星期三
}
}
代码简洁多了!

示例 5:switch 表达式(带 yield 的代码块)
当某个 case 的逻辑比较复杂,需要多行代码时,可以使用代码块和 yield。
public class SwitchExpressionWithYield {
public static void main(String[] args) {
int number = 15;
String result;
result = switch (number) {
case 1, 2, 3 -> {
System.out.println("数字很小");
yield "小数字";
}
case 10, 20, 30 -> {
System.out.println("数字是10的倍数");
yield "10的倍数";
}
default -> "其他数字";
};
System.out.println("结果是: " + result);
// 输出:
// 数字很小
// 结果是: 小数字
}
}
switch 的数据类型演进
Java 对 switch 支持的数据类型进行了扩展,使其更加强大。
| Java 版本 | 支持的数据类型 |
|---|---|
| Java 7 及之前 | byte, short, char, int, 枚举类型 |
| Java 7 | String (这是一个重要的更新) |
| Java 14+ | 所有包装类型 (Integer, Character, Long, Double, Float, Boolean) |
| Java 21+ | type 模式 (在 case 标签中直接使用类型判断) |
示例 6:switch 与 String
public class SwitchWithString {
public static void main(String[] args) {
String browser = "Chrome";
switch (browser) {
case "Chrome":
System.out.println("启动 Chrome 浏览器");
break;
case "Firefox":
System.out.println("启动 Firefox 浏览器");
break;
case "Safari":
System.out.println("启动 Safari 浏览器");
break;
default:
System.out.println("未知的浏览器");
break;
}
}
}
示例 7:switch 与 enum (枚举)
使用枚举是 switch 的一个绝佳场景,代码非常安全且清晰。
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class SwitchWithEnum {
public static void main(String[] args) {
Day today = Day.WEDNESDAY;
switch (today) {
case MONDAY:
System.out.println("新的一周开始了");
break;
case WEDNESDAY:
System.out.println("一周过半");
break;
case FRIDAY:
System.out.println("周末快到了!");
break;
default:
System.out.println("普通的一天");
break;
}
// 输出: 一周过半
}
}
示例 8:Java 21+ 的 type 模式 (Pattern Matching for switch)
这是最新的、最强大的特性,switch 可以直接根据对象的类型来执行不同的逻辑。
// Java 21+ 特性
static String format(Object obj) {
return switch (obj) {
case Integer i -> "这是一个整数: " + i;
case String s -> "这是一个字符串: " + s;
case Double d -> "这是一个双精度浮点数: " + d;
default -> "未知类型: " + obj.getClass().getName();
};
}
public static void main(String[] args) {
System.out.println(format(123)); // 输出: 这是一个整数: 123
System.out.println.format("Hello")); // 输出: 这是一个字符串: Hello
System.out.println.format(45.67)); // 输出: 这是一个双精度浮点数: 45.67
}
最佳实践和注意事项
- 总是使用
break(在传统switch语句中):除非你明确地想利用fall-through特性,否则在每个case的末尾都加上break,以避免逻辑错误。 - 考虑使用
switch表达式:对于较新的 Java 版本(14+),优先使用switch表达式,它更简洁、更安全(没有fall-through问题)。 - 为
default情况做好准备:default子句是一个很好的防御性编程实践,可以处理意外的输入值。 - 当条件范围是连续整数时,优先考虑
if-else if:如果判断if (x > 10 && x < 20),使用if-else比switch更合适。 - 当判断离散、明确的值时,优先考虑
switch:判断day是星期几,或者status是 "SUCCESS", "FAIL", "PENDING" 等,switch是更好的选择,因为它更易读。
| 特性 | 描述 |
|---|---|
传统 switch 语句 |
基于 switch(expression) 的值,跳转到匹配的 case。需要 break 来防止 fall-through。 |
switch 表达式 (Java 14+) |
可以返回一个值,使用 -> 语法,不需要 break,复杂逻辑可用 和 yield。 |
| 支持的数据类型 | 从 int, char, enum 扩展到了 String, 所有包装类型,以及最新的 type 模式。 |
fall-through |
传统 switch 的一个特性,指在 case 末尾没有 break 时,会继续执行下一个 case 的代码。 |
希望这份详细的讲解能帮助你完全掌握 Java 的 switch 语句!
