JDK-8257861 : Class::getPermittedSubclasses returns null on non-sealed class or interface
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 16
  • Submitted: 2020-12-07
  • Updated: 2020-12-09
  • Resolved: 2020-12-09
Related Reports
CSR :  
Description
Summary
-------

Change `Class.permittedSubclasses()` to return null when called on a class or interface that is not sealed.

Problem
-------

`Class.getPermittedSubclasses()` returns an empty array for sealed classes that have no permitted subclasses.  It needs to return a different value for classes that are not sealed.

Solution
--------

`Class.getPermittedSubclasses()` will return null for classes that are not sealed.

Specification
-------------

The javadoc for API `java.lang.Class.getPermittedSubclasses()` will be changed to say that if this Class object represents a primitive type, an array type, or a class or interface that is not sealed, then null is returned.  The javadoc changes are:

          * Returns an array containing {@code Class} objects representing the
          * direct subinterfaces or subclasses permitted to extend or
    -     * implement this class or interface if it is sealed. The order of such elements
    -     * is unspecified. If this {@code Class} object represents a primitive type,
    +     * implement this class or interface if it is sealed.  The order of such elements
    +     * is unspecified. The array is empty if this sealed class or interface has no
    +     * permitted subclass. If this {@code Class} object represents a primitive type,
          * {@code void}, an array type, or a class or interface that is not sealed,
    -     * an empty array is returned.
    +     * that is {@link #isSealed()} returns {@code false}, then this method returns {@code null}.
    +     * Conversely, if {@link #isSealed()} returns {@code true}, then this method
    +     * returns a non-null value.
          *
          * For each class or interface {@code C} which is recorded as a permitted
          * direct subinterface or subclass of this class or interface,
    @@ -4406,7 +4409,8 @@ public final class Class<T> implements java.io.Serializable,
          * cannot be obtained, it is silently ignored, and not included in the result
          * array.
          *
    -     * @return an array of {@code Class} objects of the permitted subclasses of this class or interface
    +     * @return an array of {@code Class} objects of the permitted subclasses of this class or interface,
    +     *         or {@code null} if this class or interface is not sealed.
          *

The javadoc changes for java.lang.Class.isSealed() are:

          * Returns {@code true} if and only if this {@code Class} object represents
          * a sealed class or interface. If this {@code Class} object represents a
          * primitive type, {@code void}, or an array type, this method returns
    -     * {@code false}.
    +     * {@code false}. A sealed class or interface has (possibly zero) permitted
    +     * subclasses; {@link #getPermittedSubclasses()} returns a non-null but
    +     * possibly empty value for a sealed class or interface.
          *
          * @return {@code true} if and only if this {@code Class} object represents a sealed class or interface.



Comments
Moving to Approved.
09-12-2020