Expression switch exception naming

Brian Goetz brian.goetz at
Wed Mar 28 18:29:25 UTC 2018

ICCE indicates that a _binary incompatible_ change was detected, which 
by definition the client cannot recover from.  Adding an enum constant 
is not a binary incompatibility (though removing one is).  
(Interestingly, neither is changing an enum to a class, if you have 
static fields for all the constants -- I learned this recently.)

However, adding an enum constant is a potential _behavioral_ 
incompatibility -- specifically, it could cause exceptions like this to 
be thrown under some circumstances.  And it is only potential because in 
order to have a problem, both the enum and the client must each bring a 
piece of the responsibility -- it is something the client could recover 
from it if it wished (by having a default).  This is an incompatibility, 
but also substantially less severe in a few ways than deleting a 
method.  (Maybe its like a method starting to return null where it never 
had before.)

If a client has a default in their switch, there's no problem.  If a 
client doesn't have a default, but provides all the known items, the 
compiler builds in a default that throws, to prevent it from being 
silently ignored.  That's all good, and things are blowing up in the 
right place with an informative message.  The behavior incompatibility 
is an interaction between the enum and the client's use of that enum.  
So I think the exception should point as much to the client as the enum.

A concrete proposal:

     UnexpectedClassChangeException <: RuntimeException
     UnexpectedSwitchTarget <: UCCE  // works both for enum and sealed 

On 3/28/2018 2:06 PM, Kevin Bourrillion wrote:
> On Wed, Mar 28, 2018 at 8:51 AM, Brian Goetz <brian.goetz at 
> <mailto:brian.goetz at>> wrote:
>         Adding a new enum value is not the same sort of
>         obviously-incompatible change as changing a static method to
>         instance, or a concrete method to abstract, which are the
>         sorts of things that trigger ICCError. ... Adding a new enum
>         constant isn't intrinsically evil.  If anything, the issue is
>         on the client, who relied on the assumption of of exhaustiveness.
> Okay, this sentiment is what I'm disagreeing with.
> I think that what we are doing here is turning that change (add 
> constant to enum) into an incompatible class change, just as much as 
> any of the other kinds. It's directly analogous to adding an interface 
> method. Clients were required to specify how to handle all the methods 
> of that interface, but then one more showed up, and those clients are 
> now broken.
> Users will find this counter-intuitive, but that's only because they 
> won't be used to it yet. They'll have to learn.
> More to the point I think: the problem isn't "on" the client code; 
> it's having jars in your runtime classpath that are newer than the 
> jars you compiled against; that's always a dangerous idea and it 
> continues to be so here. Today, an experienced developer knows that 
> there is a category of Errors that, when you see them in the absence 
> of reflection, always implicate this kind of classpath issue. I can't 
> see why this would not belong in that same category.
> -- 
> Kevin Bourrillion | Java Librarian | Google, Inc. |kevinb at 
> <mailto:kevinb at>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the amber-spec-experts mailing list