RFR: 8246778: Compiler implementation for Sealed Classes (Second Preview)
mchung at openjdk.java.net
Tue Dec 1 23:21:56 UTC 2020
On Fri, 27 Nov 2020 16:57:54 GMT, Jan Lahoda <jlahoda at openjdk.org> wrote:
> This pull request replaces https://github.com/openjdk/jdk/pull/1227.
> From the original PR:
>> Please review the code for the second iteration of sealed classes. In this iteration we are:
>> * Enhancing narrowing reference conversion to allow for stricter checking of cast conversions with respect to sealed type hierarchies
>> * Also local classes are not considered when determining implicitly declared permitted direct subclasses of a sealed class or sealed interface
>> * renaming Class::permittedSubclasses to Class::getPermittedSubclasses, still in the same method, the return type has been changed to Class<?> instead of the previous ClassDesc
>> * adding code to make sure that annotations can't be sealed
>> * improving some tests
>> Related specs:
>> [Sealed Classes JSL](http://cr.openjdk.java.net/~gbierman/jep397/jep397-20201104/specs/sealed-classes-jls.html)
>> [Sealed Classes JVMS](http://cr.openjdk.java.net/~gbierman/jep397/jep397-20201104/specs/sealed-classes-jvms.html)
>> [Additional: Contextual Keywords](http://cr.openjdk.java.net/~gbierman/jep397/jep397-20201104/specs/contextual-keywords-jls.html)
> This PR strives to reflect the review comments from 1227:
> * adjustments to javadoc of j.l.Class methods
> * package access checks in Class.getPermittedSubclasses()
> * fixed to the narrowing conversion/castability as pointed out by Maurizio
>From David's comment:
> These subtleties are what I was also getting at in the CSR discussion. If Foo lists Bar as a permitted subtype, but Bar does not extend Foo, is that an error? Should Bar not be returned by getPermittedSubclasses? The answer depends on exactly how you specify getPermittedSubclasses() and whether that aligns with reading the classfile attribute, or actually checking the runtime relationships.
As I read the current spec of `Class::getPermittedSubclasses`, it intends to return the direct subclasses or subinterfaces permitted to extend or implement this class or interface if it's sealed. If not, it should be clarified that it is the class file view.
`NestMembers` and `PermittedSubclasses` attributes are critical to correct interpretation of the class file by JVM. Prior to these two attributes, the attributes inspected by core reflection APIs are all non-critical. API like `Class::getDeclaringClass` reads `InnerClasses` attribute if present in order to determine its declaring class but the current spec does not specify the behavior on error cases (which I consider a spec bug - see JDK-8250226.)
IMO it is reasonable for `getPermittedSubclasses` (and `getNestMembers` and `getNestHost`) to return the runtime view as it returns `Class` objects since these attributes are critical to correct interpretation of the class file. It would be confusing if it returns `Foo` that is not a permitted subtype at runtime.
More information about the compiler-dev