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

时间:2019-09-22 12:17:03

标签: java switch-statement yield java-13

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

如何使用它,并且与默认的returnbreak值有什么区别?

4 个答案:

答案 0 :(得分:11)

问与答

  

我如何使用它?

  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)或构造方法({{ 3}},§8.8),而yield语句通过使封闭的switch表达式产生指定值来转移控制权。

  

中断值有什么区别?

放弃带有值的break语句,而推荐使用yield语句。

规格

§15.9附有Specification for JEP 354,它总结了我们需要了解的有关新switch的所有信息。请注意,它尚未合并到语言规范中,因为它仍然是the JLS 13,因此不是该语言的永久组成部分。

  

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

YieldStatement:
    yield Expression;
     

一条yield语句试图将控制权转移到最内层的switch表达式;此表达式称为产量目标,然后立即正常完成,并且Expression的值变为switch表达式的值。

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

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

  •   
  • 如果Expression语句的yield为空(15.1),则是编译时错误。

  •   
     

执行yield语句首先评估Expression。如果对Expression的求值由于某种原因而突然结束,则yield语句由于该原因而突然完成。如果对Expression的求值正常完成,产生值V,则yield语句突然完成,原因是产生的值为V

答案 1 :(得分:8)

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

  

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

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

此外,您甚至可以使用lambda syntax

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

使用开关表达式,整个开关块“获取一个值”,然后可以对其进行分配;您可以使用lambda样式的语法

     

虽然Java 12引入了13提炼开关表达式并对其进行了提炼,但它们是作为预览语言功能来实现的。这意味着(a)在接下来的几个发行版中仍可以更改(如在12和13之间所做的那样),并且(b)需要在编译时和运行时使用新的命令行选项--enable-对其进行解锁。预习。然后请记住,这并不是转换的最终目标–这只是迈向完全模式匹配的一步。

答案 2 :(得分:1)

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

来自doc

  

两个语句break(带有或不带有标签)和yield,   便于在switch语句和switch之间轻松消除歧义   表达式:switch语句而不是switch表达式可以是   中断声明的目标;和一个开关表达式,但不是一个开关   语句可以成为yield语句的目标。

它还提供NullPointerException安全,

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

这将导致

  

开关表达式未涵盖所有可能的输入值

答案 3 :(得分:1)

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

In Java 13 break replace by yield

String number=switch (number) {
case 1:
    yield “one”;
case 2:
    yield “two”;
befault :
    yield “Zero”;

}

Java 13仍支持箭头语法。

String number=switch (number) {
case 1 -> “one”;
case 2 -> “two”;
befault ->“Zero”;

}