Java 13 中 Switch 语句的增强
Java 12 改进了传统的 switch 语句并使其更有用。 Java 13 进一步引入了新功能。在详细介绍新功能之前,我们先来看看传统的 Switch 语句所面临的弊端。
传统Switch存在的问题
1.由于缺少break而默认fall through
默认的失败行为容易出错。让我们通过一个例子来理解它。
switch (itemCode) {
case 001 :
System.out.println("It's a laptop!");
break;
case 002 :
System.out.println("It's a desktop!");
break;
case 003 :
System.out.println("It's a mobile phone!");
break;
default :
System.out.println("Unknown device!");
}
上面的代码通过匹配相应的 case 并执行特定的代码块来工作。只要您提供必要的 break 语句,它就可以正常工作。
但是如果我们忘记了任何必需的 break 语句会发生什么:
switch (itemCode) {
case 001 :
System.out.println("It's a laptop!");
// missed out break here
case 002 :
System.out.println("It's a desktop!");
break;
}
在这里,如果我们传递 001,则第一个 case 匹配,并且代码块执行。但是由于缺少中断,执行失败并继续执行案例002 。我们得到以下错误输出:
It's a laptop!
It's a desktop!
显然,这不是预期的输出。这是意外遗漏了 break 语句的结果。
2. 不支持每个 case 的多个值
可能存在需要对多个 case 值进行类似处理的情况。但是传统的转换会跟随行为的下降。
case 001:
case 002:
case 003:
System.out.println("It's an electronic gadget!");
很多改进的开关在每个案例中接受多个值。
case 001, 002, 003 :
System.out.println("It's an electronic gadget!");
升级开关
Java 12 引入了对 switch 语句的增强,然后由Java 13 进一步修改。
让我们深入了解这个 Switch 语句改进版本的重要特性。
1. 支持每个案例多个值
通过为每个案例指定多个值,它简化了代码结构并消除了使用 fall through 的需要。
这些值需要用逗号分隔,并且 break 应该跟在 case 块之后。
switch (itemCode) {
case 001, 002, 003 :
System.out.println("It's an electronic gadget!");
break;
case 004, 005:
System.out.println("It's a mechanical device!");
break;
}
2.yield用于返回一个值
引入了新的关键字收益。它仅从 switch 分支返回值。
我们不需要在 yield 之后中断,因为它会自动终止 switch 表达式。
int val = switch (code) {
case "x", "y" :
yield 1;
case "z", "w" :
yield 2;
}
3. switch 可以用作表达式
现在可以将开关用作表达式。这意味着开关现在可以根据我们的输入返回值。开关语法略有变化以适应这种变化。开关块需要用分号分隔。 yield 关键字用于返回值。 yield 语句不需要中断。
让我们看一个代码片段以更好地理解这些更改。
String text = switch (itemCode) {
case 001 :
yield "It's a laptop!";
case 002 :
yield "It's a desktop!";
case 003 :
yield "It's a mobile phone!";
default :
throw new IllegalArgumentException(itemCode + "is an unknown device!");
}
4. 需要返回值/异常
需要 switch 表达式来指定对所有可能输入值的处理。我们要么提供所有可能的情况,要么指定默认情况。这意味着,无论输入值如何,switch 表达式都应始终返回某个值或显式抛出异常。
例如,如果将上面的代码块更改为 -
String text = switch (itemCode) {
case 001 :
yield "It's a laptop!";
case 002 :
yield "It's a desktop!";
case 003 :
yield "It's a mobile phone!";
// default :
// throw new IllegalArgumentException(itemCode + "is an unknown device!");
}
这将导致一个错误,指出所有可能的值都没有被 switch 表达式覆盖。
5.用箭头切换
为 switch 引入了新的箭头⇾语法。它可以与switch一起用作表达式和语句。
如果 ⇾ 右侧的语句在左侧完全匹配,则执行⇾右侧的语句。
在⇾的右侧,我们可以有以下任何一项 –
- 语句/表达式
- 抛出语句
- {} 堵塞
这种语法的主要优点是我们不需要 break 语句来避免默认的失败。所以规则是,如果我们需要失败,用例:否则,如果不是用例⇾ 。另请注意,对于所有 case 分支,它应该是case:或case ⇾ 。开关中不能有不同或不同的情况,否则会导致错误。
switch (itemCode) {
case 001 -> System.out.println("It's a laptop!");
case 002 -> System.out.println("It's a desktop!");
case 003,004 -> System.out.println("It's a mobile phone!");
}
正如我们在上面的代码中看到的,语法也可以用于每个 case 的多个值。
6.范围
传统 switch 中声明的变量存在直到 switch 语句结束。如果我们希望变量具有案例级别的作用域,我们可以使用Java 13 中增强开关引入的 {}。
switch (errorCode) {
case 101: {
// This variable exists just in this {} block
int num = 200;
break;
}
case 300: {
// This is ok, {} block has a separate scope
int num = 300;
break;
}
}
7.预览功能
在深入了解与增强开关相关的功能之后,值得注意的一点是——增强开关功能仅作为Java 13 中的预览功能提供。这意味着默认情况下不启用它。要使用它,我们需要显式启用它。
在编译时,将以下参数添加到 javac:
javac -- release 13 --enable-preview MyClass.java
在运行时,添加以下内容:
java --enable-preview MyClass
Java 13 中的增强开关为传统开关提供了许多令人印象深刻的功能。但是,它仍处于实验阶段,尚未准备用于生产。