章
目
录
在Java编程中,switch
语句是一种用于多分支条件判断的结构。它允许您根据表达式的值在不同的分支中进行选择。本教程将详细介绍switch
语句的语法、执行过程和各种应用情况,通过简单的代码案例来帮助初学者理解。
switch 语句
语法
switch
语句的基本语法如下所示:
switch (expression) {
case value1:
// 代码块1
break;
case value2:
// 代码块2
break;
// 更多 case 分支
default:
// 默认代码块
}
表达式值必须是以下 6 种类型之一:
- 原始数据类型,例如、
byte
、和short
char
int
- 包装类,例如、
Character
、和Byte
Short
Integer
- 枚举类型(Java 5 中添加)
- String类(Java 7中添加)
这里value1
、value2
是“编译时常量表达式”或常量(标签的值必须在编译时已知)。
break
语句用于结束当前case
块的执行,防止继续执行后续的分支。
我们可以使用一系列if-else 块来实现类似的功能,但switch语句更具可读性和简洁性。
执行过程
当switch
语句被执行时,会按照以下步骤进行:
- 计算
expression
的值。 - 将该值与每个
case
后面的常量值进行比较,如果匹配则执行对应的代码块。 - 如果找到匹配的
case
,执行其代码块,并且在代码块的结尾遇到break
语句时退出switch
语句。 - 如果没有找到匹配的
case
,执行default
代码块(如果存在)。
代码演示
在此示例中,我们使用switch语句检查今天是周末还是工作日。为了存储一周中的所有天,我们创建了一个枚举。
请注意我们如何创建总共八个返回适当true或false值的 case 标签。
传统的 switch 语句public class SwitchStatement
{
public static void main(String[] args)
{
System.out.println("Monday is : " + isWeekDay(Day.TUE));
System.out.println("Monday is : " + isWeekDay(Day.SUN));
}
public static Boolean isWeekDay(Day day)
{
Boolean result = false;
switch(day) {
case MON:
result = true;
break;
case TUE:
result = true;
break;
case WED:
result = true;
break;
case THUR:
result = true;
break;
case FRI:
result = true;
break;
case SAT:
result = false;
break;
case SUN:
result = false;
break;
default:
throw new IllegalArgumentException("Invalid day: " + day.name())
}
return result;
}
}
enum Day {
MON, TUE, WED, THUR, FRI, SAT, SUN
}
上面的例子按预期工作,但我们可以做得更好。正如我们看到的,多个 case 标签返回相同的值,因此我们可以对 case 标签进行分组以使代码更具可读性。
第一个示例的更具可读性的版本public static Boolean isWeekDay(Day day)
{
Boolean result = false;
switch(day) {
case MON, TUE, WED, THUR, FRI:
result = true;
break;
case SAT, SUN:
result = false;
break;
default:
throw new IllegalArgumentException("Invalid day: " + day.name())
}
return result;
}
仍有改进的机会。在上面的例子中,使用break语句看起来不太好。我们可以使用新的箭头语法删除break语句。它从Java 13开始可用。
public static Boolean isWeekDay(Day day)
{
Boolean result = false;
switch(day) {
case MON, TUE, WED, THUR, FRI -> result = true;
case SAT, SUN -> result = false;
default -> throw new IllegalArgumentException("Invalid day: " + day.name());
}
return result;
}
switch表达式
Java 12 引入了 switch 表达式,它可以计算整个 switch 语句的值并将其值分配给变量。它与其他普通的 Java 语句非常相似。
使用箭头语法返回值
Java 12引入了箭头语法(Arrow Case)来简化switch
语句,使其可以在分支中返回值,而无需显式使用break
。
让我们用 switch 表达式重写最后一个示例。注意行号 11我们直接将 switch 语句的值赋给变量result。
public class SwitchStatement
{
public static void main(String[] args)
{
System.out.println("Monday is : " + isWeekDay(Day.TUE));
System.out.println("Monday is : " + isWeekDay(Day.SUN));
}
public static Boolean isWeekDay(Day day)
{
Boolean result = switch(day) {
case MON, TUE, WED, THUR, FRI -> true;
case SAT, SUN -> false;
default -> throw new IllegalArgumentException("Invalid day: " + day.name());
};
return result;
}
}
enum Day {
MON, TUE, WED, THUR, FRI, SAT, SUN
}
yield带关键字的返回值
在Java 13中,引入了带有yield
关键字的switch
表达式,它允许在switch
分支中直接返回值,类似于箭头语法。
在上面的示例中,我们只在 case 语句中写入返回值。如果我们必须在从给定 case 块返回任何值之前执行多个语句该怎么办?
在这种情况下,yield
关键字有助于从多语句块返回计算值。
在给定的示例中,我们只编写了一条打印语句。您可以根据需要编写任意数量的语句。
public static Boolean isWeekDay(Day day)
{
Boolean result = switch(day) {
case MON, TUE, WED, THUR, FRI -> {
System.out.println("It's Weekday");
yield true;
}
case SAT, SUN -> {
System.out.println("It's Weekend");
yield false;
}
default -> throw new IllegalArgumentException("Invalid day: " + day.name());
};
return result;
}
使用instanceof进行类型检查
在Java 17中,引入了对switch
语句的增强功能,可以更方便地使用instanceof
运算符来进行类型检查。这种用法可以取代传统的if-else
链。例如:
传统上,如果我们必须编写一段代码来检查实例类型并执行一些逻辑,那么就是这样:
Object o;
if (o instanceof String)
{
String s = (String) o;
String.format("String %s", s)
}
else if (o instanceof Integer)
{
Integer i = (Integer) o;
String.format("int %d", i)
}
else if (o instanceof Double)
{
Double d = (Double) o;
String.format("double %f", d)
}
在Java 17中,我们可以通过以下方式重写整个表达式;
Object o;
switch (o)
{
case Integer i -> String.format("int %d", i);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> o.toString();
}
处理null值
在过去的Java版本中,switch
语句无法直接处理null
值。但是,在Java 14中,引入了新的switch
表达式,可以使用null
作为表达式。例如:
Java 17 之前:
if (s == null) {
System.out.println("oops!");
return;
}
switch (s) {
case "Foo", "Bar" -> System.out.println("Great");
default -> System.out.println("Ok");
}
在Java17中:
switch (s) {
case null -> System.out.println("Oops");
case "Foo", "Bar" -> System.out.println("Great");
default -> System.out.println("Ok");
}
限制条件
Case标签值必须在数据类型范围内
请注意,用作case标签的常量表达式的值必须在switch表达式的数据类型范围内。
在Java中,byte数据类型的范围是-128到127,因此以下代码将无法编译,因为第二个case标签为150,超出了byte数据类型的范围:
byte b = 10;
switch (b) {
case 5:
b++;
break;
case 150: // 编译错误: 150 超过了 127
b--;
break;
default:
b = 0;
}
不允许重复的Case标签
另一个需要注意的重要点是,在switch语句中,两个case标签不能相同。以下代码片段将无法编译,因为重复出现了case标签10:
int num = 10;
switch (num) {
case 10:
num++;
break;
case 10: // 编译错误. 重复case label 10
num--;
break;
default:
num = 100;
}
总结
通过以上示例,您应该对Java中的switch
语句有了更好的理解。它是一个强大的工具,用于处理多个分支条件,而不必编写冗长的if-else
语句。随着Java版本的升级,switch
语句也得到了许多增强和改进,使其更加灵活和实用。希望本教程能帮助您在编程中更好地使用switch
语句。
文章目录 前言 第1章 Java语言基础 第2章 流程控制语句 第3章 面向对象编程 第4章 Java 字符 […]