Java 13 中的新关键字“yield”是什么意思?

2022-08-31 21:02:25

Java 13 为表达式引入了 yield 关键字。switch

我如何使用它,与默认值或值有什么区别?returnbreak


答案 1

问与答

我该如何使用它?

  1. 当需要完整块时,使用箭头标签:

    int value = switch (greeting) {
        case "hi" -> {
            System.out.println("I am not just yielding!");
            yield 1;
        }
        case "hello" -> {
            System.out.println("Me too.");
            yield 2;
        }
        default -> {
            System.out.println("OK");
            yield -1;
        }
    };
    
  2. 使用传统块:

    int value = switch (greeting) {
        case "hi":
            System.out.println("I am not just yielding!");
            yield 1;
        case "hello":
            System.out.println("Me too.");
            yield 2;
        default:
            System.out.println("OK");
            yield -1;
    };
    

与默认回报有什么区别?

语句将控制权返回给方法 (§8.4§15.12) 或构造函数§8.8§15.9的调用方,而语句则通过使封闭开关表达式生成指定的值来传递控制权。returnyield

与中断值有什么区别?

with value 语句被删除,取而代之的是语句。breakyield

规范

JLS 13附带了JEP 354的规范,它总结了我们需要了解的有关新.请注意,它未合并到语言规范中,因为它仍然是预览功能,因此还不是语言的永久部分。switch

语句通过使封闭表达式生成指定的值来传递控制权。yieldswitch

YieldStatement:
    yield Expression;

语句尝试将控制权转移到最内层的封闭开关表达式;这个表达式称为 yield 目标,然后立即正常完成,并且 的值成为表达式的值。yieldExpressionswitch

  • 如果语句没有 yield 目标,则为编译时错误。yield

  • 如果目标包含任何包含 yield 语句的方法、构造函数、初始值设定项或 lambda 表达式,则这是编译时错误。yield

  • 如果语句的 void (15.1),则为编译时错误。Expressionyield

执行语句首先计算 .如果由于某种原因突然完成了对语句的评估,则由于该原因,语句突然完成。如果计算正常完成,产生一个值,则该语句突然完成,原因是具有值的收益。yieldExpressionExpressionyieldExpressionVyieldV


答案 2

作为 JEP 354 (Java 13) 的一部分,您可以在 switch 中生成值(可以选择将其分配给变量)

yield 语句以生成一个值,该值成为封闭开关表达式的值。

int j = switch (day) {
    case MONDAY  -> 0;
    case TUESDAY -> 1;
    default      -> {
        int k = day.toString().length();
        int result = f(k);
        yield result;
    }
};

我认为你的困惑是Java 12上的JEP 325使用break来返回值:

我们已经扩展了 break 语句以采用一个参数,该参数成为封闭开关表达式的值。

int j = switch (day) {
     case MONDAY  -> 0;
     case TUESDAY -> 1;
     default      -> {
         int k = day.toString().length();
         int result = f(k);
         break result;

此外,您甚至可以使用 lambda 语法

boolean result = switch (ternaryBool) {
    case TRUE -> true;
    case FALSE -> false;
    case FILE_NOT_FOUND -> throw new UncheckedIOException(
        "This is ridiculous!",
        new FileNotFoundException());
    // as we'll see in "Exhaustiveness", `default` is not necessary
    default -> throw new IllegalArgumentException("Seriously?!