[sealed] Sealed local classes?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Oct 9 23:22:20 UTC 2019

Good catch! I fully support the restriction.

In your other email I guess you are referring to anonymous classes 
implementing a sealed interface, right? E.g.

sealed interface Foo {
     void m();

     /* static final */ Foo f1 = new Foo() { ... }
     /* static final */ Foo f2 = () -> {};


That is, this should be rejected on same ground - given that inference 
would end up putting mangled type names in the permits clause (well, at 
least for the anonymous, in the case of the lambda there's not even a 
name ;-)).

Dunno about the above code - it's not completely unreasonable (it's not 
hard to imagine a functional interface having some pre-wired default 
value - e.g. like Predicate::FALSE). Another angle is, instead of 
banning,these weird subclasses, we just don't add them to the permits 
clause (*)

(*) there's also a technical reason as to why inferring permitted types 
based on things inside field initializers and method bodies is not 
sound: again it has to do with annotation processing. Presumably you 
want all your inference completed before annotation processors are run. 
But, by design, annotation processor only requires declarations to be 
processed, not entire method bodies. So it would not be possible, under 
the current regime at least, to gather up all permitted types inside all 
method bodies _before_ annotation processing.


On 09/10/2019 22:26, Brian Goetz wrote:
> It is allowable, though somewhat silly, to put the `final` modifier on 
> local classes.
> From a hierarchy-protection point of view, allowing local classes to 
> be `sealed` is also silly, as it cannot be extended from outside the 
> method anyway, and even if it could, such types can't show up in APIs 
> that are accessible from outside.
> From an exhaustiveness point of view, though, one can imagine having a 
> sealed local hierarchy (sum of records) that will be switched over 
> within the method, though one would have to work pretty hard to 
> imagine that.
> Note that a local class cannot be a subtype of a sealed type declared 
> outside the same method (*), since it can't be denoted in the permits 
> clause.
> (*) unless the permits clause is inferred.  Yuck.  Now a mangled name 
> would go into the PermittedSubtypes attribute.
> Proposal: ban `sealed` and `non-sealed` modifiers on _local_ classes 
> and interfaces.

More information about the amber-spec-experts mailing list