[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.
Maurizio
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