CSR :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
Summary ------- Switch expressions were a preview feature in Java SE 12 (see [JEP 325](https://bugs.openjdk.java.net/browse/JDK-8192963) and the [CSR](https://bugs.openjdk.java.net/browse/JDK-8207241)). Based on experience with the feature, the value `break` statement which yields a value from a switch expression should be replaced by a `yield` statement. Problem ------- The value `break` statement is confusing to developers because it overloads the `break` with label statement. For example, `break L;` would be a labeled `break` statement in a `for` loop (transferring control out of the loop without yielding any value) but would be a value `break` statement in a switch expression (yielding the value of variable `L` as the result of the switch). In addition, the need for a value `break` statement in a switch expression is quite rare -- only when the RHS of a `case ... ->` is a block rather than an expression -- but the reuse of the `break` keyword reminds developers of the almost universal need for `break` in a switch statement; this tends to hurt understanding of switch expressions more broadly. Solution -------- The value `break` statement is replaced by a new `yield` statement. As `yield` is a valid identifier, it is not practicable to start treating it as a keyword. Even treating it as a restricted keyword leads to the potential problem that parsing a `yield` statement might require unlimited lookahead to determine if the character sequence `yield` should be tokenized as a keyword or as an identifier. We propose a simpler strategy, building on the approach taken when adding `var` in JDK 10: `var` and now `yield` are considered *restricted identifiers*. Restricted identifiers are not valid type identifiers, i.e., you cannot declare a type called `var` or `yield`. In addition we consider `yield` to be an invalid name for an unqualified method invocation. This means that the phrase `yield (3);` will be parsed as a `yield` statement and not as an unqualified invocation of a `yield` method. Invocations of methods called `yield` must be qualified, e.g., `Thread.yield();` or `this.yield();`. It is still permitted to declare an instance variable or local variable called `yield`, and to use such a variable without qualification, even in a statement context such as `yield++;` or `yield = 1;`. For such usages, the compiler is expected to perform limited lookahead and disambiguate between YieldStatement and ExpressionStatement. Analysis of the Java SE API reveals only one method named `yield`; the occurrence of a method named `yield` in other large codebases is similarly rare. This update will require corresponding changes in the JDK-specific [Compiler Tree API](https://docs.oracle.com/en/java/javase/12/docs/api/jdk.compiler/com/sun/source/tree/package-summary.html). Specification ------------- The updated JLS changes for switch expressions is attached, and also [available online](http://cr.openjdk.java.net/~gbierman/jep354-jls-20190528.html). The specdiff for the Trees API changes is attached, and also [available online](http://cr.openjdk.java.net/~jlahoda/8223303/specdiff.01a/overview-summary.html).
|