36

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

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

4

4 回答 4

39

问答

我该如何使用它?

  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;
    };
    

与默认退货有什么区别?

return语句将控制权返回给方法的调用者第 8.4 节第 15.12 节)或构造函数第 8.8 节第 15.9 节),而yield语句通过使封闭switch表达式产生指定值来转移控制权。

中断值有什么区别?

break删除了 with value 语句以支持语句yield

规格

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

语句通过yield使封闭switch表达式产生指定值来转移控制。

YieldStatement:
    yield Expression;

一条yield语句试图将控制权转移到最里面的封闭式 switch 表达式;这个表达式,称为yield target,然后立即正常完成,并且 的值Expression成为switch表达式的值。

  • 如果yield语句没有 yield 目标,这是一个编译时错误。

  • 如果yield目标包含包含 yield 语句的任何方法、构造函数、初始化程序或 lambda 表达式,则会出现编译时错误。

  • 如果语句的 void (15.1)Expression是编译时错误。yield

语句的执行yield首先评估Expression. 如果对 的求值Expression由于某种原因突然完成,那么yield语句会因为这个原因而突然完成。如果评估Expression正常完成并产生一个 value V,那么该yield语句会突然完成,原因是 yield with value V

于 2019-09-22T13:13:58.557 回答
10

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

yield 语句产生一个值,该值成为封闭 switch 表达式的值。

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 语句以接受一个参数,该参数成为封闭 switch 表达式的值。

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?! ");
};

使用 switch 表达式,整个 switch 块“得到一个值”,然后可以赋值;你可以使用 lambda 风格的语法

虽然 Java 12 引入并 13 改进了 switch 表达式,但它们是作为预览语言功能这样做的。这意味着(a)它仍然可以在接下来的几个版本中发生变化(就像它在 12 和 13 之间所做的那样)和(b)它需要在编译时和运行时使用新的命令行选项--enable-解锁预习。然后请记住,这不是 switch 的最后阶段——它只是通向完全模式匹配的一步。

于 2019-09-22T12:24:59.547 回答
1

yield标记要从 switch 分支返回的值。它终止了 switch 表达式,你不需要在它之后有 break。

来自文档

break(带或不带标签)和yield 这两个语句有助于轻松消除switch 语句和switch 表达式之间的歧义:switch 语句而不是switch 表达式可以是break 语句的目标;switch 表达式而不是 switch 语句可以是 yield 语句的目标。

它还提供,NullPointerException安全,

String message = switch (errorCode) {
    case 404:
        yield "Not found!";
    case 500:
        yield "Internal server error!";
    // No default
};

这将导致,

switch 表达式不涵盖所有可能的输入值

于 2019-09-22T12:36:30.637 回答
1

在 java 13 中 break 替换为 yield。这是 java 13 中定义的预览功能之一。在 Java 12 中,我们可以使用 break 从开关中返回一个值。但是在 java 13 中 yield 用于 switch 表达式的返回值。

在 Java 13 中 break 替换为 yield

String number = switch (number) {
    case 1:
        yield "one";
    case 2:
        yield "two";
    default:
        yield "Zero";
}

Java 13 仍然支持箭头语法。

String number = switch (number) {
    case 1 -> "one";
    case 2 -> "two";
    default -> "Zero";
}
于 2019-11-19T08:14:32.577 回答