What does the new keyword "yield" mean in Java 13?
Q&A
How can I use it?
With arrow labels when a full block is needed:
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; } };
With traditional blocks:
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; };
What's the difference to a default return?
A return
statement returns control to the invoker of a method (§8.4, §15.12) or constructor (§8.8, §15.9) while a yield
statement transfers control by causing an enclosing switch
expression to produce a specified value.
What's the difference to a break value?
The break
with value statement is dropped in favour of a yield
statement.
Specification
There is Specification for JEP 354 attached to the JLS 13 which sums up everything we need to know about the new switch
. Note that it wasn't merged into the language specification because it's still a preview feature and, thus, not yet a permanent part of the language.
A
yield
statement transfers control by causing an enclosingswitch
expression to produce a specified value.YieldStatement: yield Expression;
A
yield
statement attempts to transfer control to the innermost enclosing switch expression; this expression, which is called the yield target, then immediately completes normally and the value of theExpression
becomes the value of theswitch
expression.
It is a compile-time error if a
yield
statement has no yield target.It is a compile-time error if the
yield
target contains any method, constructor, initializer, or lambda expression that encloses the yield statement.It is a compile-time error if the
Expression
of ayield
statement is void (15.1).Execution of a
yield
statement first evaluates theExpression
. If the evaluation of theExpression
completes abruptly for some reason, then theyield
statement completes abruptly for that reason. If evaluation of theExpression
completes normally, producing a valueV
, then theyield
statement completes abruptly, the reason being a yield with valueV
.
As part of JEP 354 (Java 13), you can yield value in switch (optionally assign it to variable)
yield statement to yield a value, which becomes the value of the enclosing switch expression.
int j = switch (day) { case MONDAY -> 0; case TUESDAY -> 1; default -> { int k = day.toString().length(); int result = f(k); yield result; } };
I think your confusion is with JEP 325 on Java 12 that use break to return value:
we have extended the break statement to take an argument, which becomes the value of the enclosing switch expression.
int j = switch (day) { case MONDAY -> 0; case TUESDAY -> 1; default -> { int k = day.toString().length(); int result = f(k); break result;
In addition, you can even use 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?! ð¤¬"); };
With switch expressions, the entire switch block "gets a value" that can then be assigned; you can use a lambda-style syntax
While Java 12 introduces and 13 refines switch expressions, they do so as a preview language feature. That means (a) it can still change over the next few releases (as it did between 12 and 13) and (b) it needs to be unlocked, at compile time and run time, with the new command line option --enable-preview. Then keep in mind that this isn’t the endgame for switch – it’s just a step on the way to full pattern matching.