📜  Java 13 中 Switch 语句的增强

📅  最后修改于: 2022-05-13 01:55:12.653000             🧑  作者: Mango

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 中的增强开关为传统开关提供了许多令人印象深刻的功能。但是,它仍处于实验阶段,尚未准备用于生产。