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
