Does someone has done the work to check if there are a few?, some?, a lot? of 
codes that catch IncompatibleClassChangeError in the wild ?

Because replacing a exception by another usually leads to subtle bugs, 
especially when an Error which is replaced by an RuntimeException.
Sadly catch(RuntimeException) / catch(Exception) are the usual trouble makers.

Rémi

----- Original Message -----
> From: "Gavin Bierman" <[email protected]>
> To: "amber-spec-experts" <[email protected]>
> Sent: Monday, November 14, 2022 1:38:46 PM
> Subject: Late change to JEP 433

> Dear Experts,
> 
> As we put the final polish on features for JDK20, we noticed that we have an
> opportunity to make a very small breaking change (as part of the preview
> feature) to simplify our lives. I’m writing to see what you think.
> 
> tldr: A switch expression over an enum class should throw MatchException 
> rather
> than IncompatibleClassChangeError if no switch label applies at runtime.
> 
> Details:
> 
> When we introduced switch expressions, we opted for a design where the switch
> body had to be exhaustive. When switching over an enum type, a switch body 
> with
> case labels supporting all the enum constants for the enum type is considered
> exhaustive, meaning a default clause is not needed.
> 
> However, there is a possibility that the enum class is changed after 
> compilation
> of the switch expression, and a new enum constant added. Then when executing
> the switchexpression, no label would apply.
> 
> The question we faced in JDK14 was what to do at this point. We decided on
> IncompatibleClassChangeError as that was a pre-existing exception that was
> generally understood by developers as a signal that things have got out of 
> sync
> and re-compilation is needed.
> 
> Back to the present day, with the support of pattern switches, we can now 
> write
> switches over a sealed type. When switching over a sealed type, a switch body
> with case labels with type patterns matching all the permitted subclasses is
> considered exhaustive, meaning a default clause is not needed.
> 
> If the sealed hierarchy has been changed after compilation of the switch, it 
> is
> possible that when executing the switch that no label would apply. In this 
> case
> we have settled on throwing a MatchException.
> 
> Throughout our design process, we have noticed the connection between enum
> classes/enum constants and sealed class/permitted subclasses – they are
> essentially the same thing up the term/type hierarchy. Moreover, in a future
> release, we plan to support case labels with a mix of sealed class type
> patterns and enum constants.
> 
> But we now have an inconsistency - one throws IncompatibleClassChangeException
> in a bad situation and the other MatchException which will make this future
> development almost impossible. We need these cases to throw the same 
> exception:
> MatchException. So we propose to make the small breaking case to the language
> that switch expressions over enum classes throw MatchException should no 
> switch
> label apply in the switch body.
> 
> People who deliberately change their enum classes by adding new constants, and
> do not recompile their switches over this enum class, and rely on this 
> throwing
> ICCE will notice this breaking change. We think this is a vanishingly small 
> set
> of developers. The vast majority of developers, on the other hand, will thank
> us for this unification, especially if it enables other new features down the
> road.
> 
> What do you think?
> 
> Thanks,
> Gavin

Reply via email to