New JEP: Switch Expressions for the Java Language

Brian Goetz brian.goetz at
Sun Dec 10 17:56:51 UTC 2017

Here’s another way of looking at expression switch.  This is a translation-centric view, but may be useful both as a mental model and as a specification approach as well. 

If I have an expression switch:

    T y = switch (x) {
        case A -> e;
        case B -> f;

We could implement by desugaring the switch into the invocation of a synthetic method:

    T y = m$switch(x, a, b, ...)

where a, b, ... are locals mentioned in e and f.  And m$switch() is:
 - replace "case L -> e" with "case L: return e"
 - replace case L -> block with "case L: block"**
 - m$switch() is declared to throw any checked exceptions thrown by switch arms.

** This is exploiting the otherwise-unfortunate pun between local return and nonlocal return.

Where does this leave us?

 - Can't do nonlocal return out of an expression switch.  That's good -- that's what we wanted anyway.
 - Can't reference mutable locals.  That seems OK, but see below.  
 - Fallthrough in expression switches (other than OR patterns) is cleverly prohibited by the syntax of switch expressions.  

This mental model leaves us pretty close to where we thought we wanted to land anyway (whether or not we actually translate like this.)

Note that the “effectively final” constraint is stronger than it needs to be to support this model.  The reason that captured locals of even stack-confined lambdas need to be effectively final is that the capture point and the invocation point of the lambda might be different, and so there would be two credible answers for what the following program could print:

    int x = 3;
    Runnable r = () -> println(x);

    x = 4;;

You could argue for either 3 or 4 here, so to eliminate the potential for confusion (among other reasons) we say “no non-effectively-final captures”.  But, for an expression switch desugared as above, the capture point and invocation point are guaranteed to be the same.  So we could easily say that its OK to reference (but not mutate) mutable locals in a switch expression, and it would be consistent with the model given.  

Note that “consistency” offers us no guidance here; in one approach we’re consistent with lambdas but inconsistent with, say, conditional expressions (which can reference and even mutate mutable locals.)  

So, candidates for what happens here:
 - like conditional expression — anything goes, locals can be mutated
 - can read locals, but can’t write them — a reasonable position, but unlike anything else so far
 - like lambdas - effectively final locals only.

> On Dec 7, 2017, at 5:33 PM, Brian Goetz <brian.goetz at> wrote:
> We've separated out a package of standalone improvements to `switch` (switch expressions, case null, and case alternation) into their own JEP:

More information about the amber-spec-observers mailing list