switch 语句的基本语法
switch 语句会评估一个表达式,然后将表达式的值与 case 子句中的值进行比较,如果找到匹配的 case,则执行该 case 后面的代码,直到遇到 break 语句或 switch 语句的结束大括号 。
switch (expression) {
case value1:
// 当 expression 的值等于 value1 时,执行这里的代码
// ...
break; // 可选,但强烈推荐
case value2:
// 当 expression 的值等于 value2 时,执行这里的代码
// ...
break; // 可选,但强烈推荐
case value3:
// 当 expression 的值等于 value3 时,执行这里的代码
// ...
break; // 可选,但强烈推荐
default:
// expression 的值不与任何一个 case 匹配,则执行这里的代码
// ...
break; // 可选,但强烈推荐
}
关键点解析:
switch (expression):expression是一个表达式,其结果必须是以下几种类型之一:byteshortcharint- 枚举类型 (Java 5+)
String类型 (Java 7+)- 包装类 (
Byte,Short,Character,Integer,Enum) (Java 5+)
case value::value必须是一个常量或字面量(不能是变量),并且类型必须与switch表达式的类型兼容,每个case值必须是唯一的。break;: 这是switch语句中非常重要的一个概念。- 如果在一个
case中没有break语句,程序会继续执行下一个case的代码,这种现象称为 "穿透" (fall-through)。 - 有时,"穿透"是有意为之的(多个
case执行相同的代码块),但大多数情况下,它是一个容易出错的逻辑漏洞。除非你明确知道需要“穿透”,否则一定要在每个case的末尾加上break。
- 如果在一个
default:: 这是可选的,如果没有任何case的值与switch表达式的值匹配,则会执行default块中的代码,它的位置可以任意,但通常放在最后。
使用示例
示例 1:基本用法(带 break)
这是最常见的用法,为每个条件执行独立的代码块。
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 语句缺失时会发生什么。
public class SwitchFallThrough {
public static void main(String[] args) {
int grade = 'B'; // 字符 'B' 会自动提升为 int 类型 (ASCII 码 66)
switch (grade) {
case 'A':
System.out.println("优秀!");
case 'B':
System.out.println("良好!");
case 'C':
System.out.println("及格。");
case 'D':
System.out.println("不及格。");
break; // 只有在这里才停止
default:
System.out.println("无效的等级。");
}
}
}
输出结果:
良好!
及格。
不及格。
解释:
因为 grade 的值是 'B',程序从 case 'B': 开始执行,由于没有 break,它会继续向下执行 case 'C' 和 case 'D' 的代码,直到遇到 break 或 switch 结束。
示例 3:利用“穿透”简化代码
有时,“穿透”是有用的,当多个 case 需要执行相同的操作时。
public class SwitchSimplified {
public static void main(String[] args) {
int month = 2;
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
System.out.println("这个月有 31 天。");
break;
case 4:
case 6:
case 9:
case 11:
System.out.println("这个月有 30 天。");
break;
case 2:
System.out.println("这个月可能是 28 或 29 天。");
break;
default:
System.out.println("无效的月份。");
}
}
}
// 输出: 这个月可能是 28 或 29 天。
示例 4:使用 String 类型 (Java 7+)
从 Java 7 开始,switch 语句可以直接支持 String 类型。
public class SwitchWithString {
public static void main(String[] args) {
String fruit = "Apple";
switch (fruit) {
case "Apple":
System.out.println("选了苹果。");
break;
case "Banana":
System.out.println("选了香蕉。");
break;
case "Orange":
System.out.println("选了橙子。");
break;
default:
System.out.println("未知的水果。");
}
}
}
// 输出: 选了苹果。
示例 5:使用枚举类型 (Java 5+)
枚举是与 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("普通的一天。");
}
}
}
// 输出: 周中,工作日过半!
switch 表达式 (Java 14+ - 预览功能,Java 14+ 正式功能)
从 Java 14 开始,switch 不仅可以作为语句,还可以作为 表达式 来使用,这带来了巨大的便利,可以让你写出更简洁、更函数式的代码。
switch 表达式有以下特点:
- 它有返回值。
- 不允许“穿透”,每个
case必须明确提供值(使用->或yield)。 - 不需要
break语句。
switch 表达式的语法
// 使用箭头 (->) 语法 (推荐)
result = switch (expression) {
case value1 -> code_block_1;
case value2 -> code_block_2;
case value3 -> code_block_3;
default -> code_block_default;
};
// 使用 yield 返回值 (当代码块有多行时)
result = switch (expression) {
case value1 -> {
// 多行代码
int x = 10;
int y = 20;
yield x + y; // 使用 yield 返回一个值
}
case value2 -> 42;
default -> 0;
};
示例:将示例 1 改写为 switch 表达式
public class SwitchExpressionExample {
public static void main(String[] args) {
int day = 3;
String dayName = switch (day) {
case 1 -> "星期一";
case 2 -> "星期二";
case 3 -> "星期三";
case 4 -> "星期四";
case 5 -> "星期五";
case 6 -> "星期六";
case 7 -> "星期日";
default -> "无效的日期";
};
System.out.println("今天是 " + dayName);
}
}
// 输出: 今天是 星期三
这个版本比 switch 语句更简洁、更安全,因为它消除了“穿透”的风险,并且直接返回一个值。
switch 与 if-else if-else 的选择
| 特性 | switch 语句/表达式 |
if-else if-else 语句 |
|---|---|---|
| 适用场景 | 检查一个变量等于几个固定值中的一个。 | 检查复杂的条件,如范围 (>, <)、布尔表达式、多个变量的组合。 |
| 可读性 | 当条件是简单的等值比较时,switch 通常更清晰。 |
对于复杂逻辑,if-else 结构更自然。 |
| 灵活性 | 较低,只能用于特定类型和等值比较。 | 非常高,可以用于任何布尔表达式。 |
| “穿透” | 旧版 switch 语句有“穿透”风险,新版 switch 表达式已消除。 |
没有“穿透”概念。 |
| 返回值 | switch 表达式可以返回值。 |
if-else 本身不返回值,但可以通过三元运算符 或将其包裹在方法中来模拟。 |
简单总结:
- 如果你只是想根据一个变量的值来执行不同的代码块,并且这个值是有限的、已知的(如
int,String,enum),优先使用switch。 - 如果你的判断条件更复杂,涉及范围、逻辑与/或、或者多个变量,那么使用
if-else if-else。
希望这份详细的解释能帮助你完全掌握 Java 中 switch 的用法!
