1. 概述

在编程中,我们常常使用switch语句来将一个值转换为另一个。在早期的Java版本中,这通常需要我们在单独的函数中嵌套switch,每个casereturn语句返回结果,或者需要在函数中为每个case临时存储一个值供后续使用。

自Java 14起,switch表达式的yield关键字提供了一种更佳的处理方式。

2. yield关键字

yield关键字允许我们在switch表达式中通过返回一个值,使这个值成为switch表达式的值。这意味着我们可以将switch表达式的值赋给一个变量。此外,使用yieldswitch表达式中提供了对所有情况覆盖的隐式检查,从而使代码更加健壮。

让我们看一些例子。

2.1. 使用箭头运算符的yield

首先,假设我们有以下枚举和switch语句:

public enum Number {
    ONE, TWO, THREE, FOUR;
}

String message;
switch (number) {
    case ONE:
        message = "Got a 1";
        break;
    case TWO:
        message = "Got a 2";
        break;
    default:
        message = "More than 2";
}

我们可以将其转换为switch表达式,并结合使用yield和箭头运算符:

String message = switch (number) {
    case ONE -> {
        yield "Got a 1";
    }
    case TWO -> {
        yield "Got a 2";
    }
    default -> {
        yield "More than 2";
    }
};

yield根据number的值设置switch表达式的值。

2.2. 使用冒号分隔的yield

我们也可以使用yield和冒号分隔符创建switch表达式:

String message = switch (number) {
    case ONE:
        yield "Got a 1";
    case TWO:
        yield "Got a 2";
    default:
        yield "More than 2";
};

这段代码的行为与上一节相同。但箭头运算符更清晰,也较少忘记添加yield(或break)语句的风险。

需要注意的是,在同一个switch表达式中,我们不能混合使用冒号和箭头分隔符。

3. 全面性

使用switch表达式和yield的另一个优点是,如果我们的情况覆盖不全,编译器会报错。让我们从箭头运算符的switch表达式中移除默认情况来验证:

String message = switch (number) {
    case ONE -> {
        yield "Got a 1";
    }
    case TWO -> {
        yield "Got a 2";
    }
};

上述代码在number上会产生错误:“switch 表达式没有涵盖所有可能的输入值”。

我们可以添加回默认情况,或者明确地覆盖number的所有其他可能值:

String message = switch (number) {
    case ONE -> {
        yield "Got a 1";
    }
    case TWO -> {
        yield "Got a 2";
    }
    case THREE, FOUR -> {
        yield "More than 2";
    }
};

switch表达式强制我们的情况覆盖必须全面无遗漏。

4. 总结

在这篇文章中,我们探讨了Java中的yield关键字,它的用法以及一些优势。如常,我们示例的完整源代码可以在GitHub上找到。