了解 Java 的 switch 表达式
提到 switch
, 所有 Java 开发人员应该都不陌生。switch
根据变量的值来执行不同的逻辑,用来替代多分支的if/else
。
不过 switch
语句在使用时存在一些常见问题。
首先是 switch
语句中的 case
分支的执行,默认是往下进行的,需要添加 break
来跳出 switch
的执行。这种行为很容易产生bug。比如,下面代码中的 trafficControl
方法,在参数值是 RED
时,会执行全部的 case
分支,因为并没有添加 break
语句。
public class SwitchStatement {
enum TrafficColor {
RED, YELLOW, GREEN
}
public void trafficControl(TrafficColor color) {
switch (color) {
case RED:
this.stop();
case GREEN:
this.go();
default:
this.watchOut();
}
}
private void go() {
System.out.println("Go!");
}
private void stop() {
System.out.println("Stop!");
}
private void watchOut() {
System.out.println("Be careful!");
}
}
switch
语句的另外一个常见用法是在不同的分支中对同一个变量进行赋值。如下面的代码所示。这种写法比较繁琐。
public class SwitchStatementAssignment {
enum TrafficColor {
RED, YELLOW, GREEN
}
public String getMessage(TrafficColor color) {
String message;
switch (color) {
case RED:
message = "Stop!";
break;
case GREEN:
message = "Go!";
break;
default:
message = "Be careful!";
}
return message;
}
}
为了解决这两个问题,可以用到 switch
表达式和箭头标签。
switch
表达式在 Java 12 中以预览功能的形式引入,在 Java 13 中再次预览,在 Java 14 中成为正式功能。
switch
可以作为表达式来使用,因此可以有自己的值。这就简化了赋值操作。switch
表达式的值由分支来确定。下面的代码展示了 switch
表达式的基本用法。
public class SwitchExpression {
public String formatGifts(int number) {
return switch (number) {
case 0 -> "no gifts";
case 1 -> "only one gift";
default -> number + " gifts";
};
}
}
在上述代码中,switch
表达式使用的不是传统的冒号,而是箭头。在使用了箭头之后,代码执行不会转到下一个分支,相当于添加了 break
。在下面的代码中,同样的 trafficControl
方法,使用箭头标签之后,就不再需要使用 break
。
public class SwitchLabel {
enum TrafficColor {
RED, YELLOW, GREEN
}
public void trafficControl(TrafficColor color) {
switch (color) {
case RED -> System.out.println("Stop!");
case YELLOW -> System.out.println("Be careful!");
case GREEN -> System.out.println("Go!");
}
}
}
大多数情况下,箭头标签之后使用单个表达式就可以满足需求。如果有复杂的逻辑,可以使用代码块。这个时候就需要用 yield
来提供值。
public class YieldValue {
public String formatGifts(int number) {
return switch (number) {
case 0 -> "no gifts";
case 1 -> "only one gift";
default -> {
if (number < 0) {
yield "no gifts";
} else {
yield number + " gifts";
}
}
};
}
}
在使用传统标签的 switch
语句中,也是可以使用 yield
。
public class YieldValue2 {
public String formatGifts(int number) {
return switch (number) {
case 0:
yield "no gifts";
case 1:
yield "only one gift";
default: {
if (number < 0) {
yield "no gifts";
} else {
yield number + " gifts";
}
}
};
}
}
关于 switch
表达式的内容,就介绍到这里。相应的视频见我的B站。