JEP-360 Sealed types and non-accessible subtypes

Kłeczek, Michał michal at kleczek.org
Sun Dec 1 19:49:48 UTC 2019



On 01/12/2019 19:04:37, "Brian Goetz" <brian.goetz at oracle.com> wrote:

>>  I think there is a subtle difference here. The subtlety is that traditionally adding a subtype does not require any change in the client code depending on the super type (as per Liskov Substitution Principle).
>>  I am wondering how surprising it will be that adding a non-public class (in the same compilation unit as the sealed super type) breaks existing clients.
>
>If all the types are public/exported, and you add a first non-exported one, then yes, this is binary-but-not-source-compatble
While formally adding a subtype might be a compatible change (as the 
default case is always there) - in practice this is a breaking change
(I cannot upgrade to a new version of the library _without_ any code 
changes - ie. by just replacing a jar file).
Such a change is actually equivalent to removing a method.

>  (but the impact on clients is still pretty minimal, they need to add a default clause on their next recompilation.)  If you _already_ have at least one nonpublic/nonexported subtype, then adding a second does not risk breaking anything, since clients would _already_ be doing so.
Indeed.

>
>
>In any case, this is a deliberate tradeoff; it has to be possible to evolve sealed APIs somehow, otherwise it is too brittle.  This seemed the best place to draw this line.
>
>>  Maybe - if exhaustiveness check is so important - it is better to force explicit declaration of permitted subtypes - at least that would make it clear that adding one is an API change.
>
>We did consider this, but this also seemed like a bad tradeoff — making all APIs explicitly list all their subtypes — when they are declared RIGHT THERE — would be seen as just being mean, for little benefit.  So again, this seemed the best way to balance the various concerns.
>
So it looks like the best practice for API designers is to _always_ add 
a non-public permitted subtype to force clients to implement default 
case.
I even have a good name for this subtype: DefaultCase :)

Thanks for sharing your thoughts.

Michal



More information about the amber-dev mailing list