Document null handling in core reflection APIs

XMLWordPrintable

    • Type: CSR
    • Resolution: Unresolved
    • Priority: P4
    • 26
    • Component/s: core-libs
    • None
    • behavioral
    • minimal
    • Hide
      Class.isNestmateOf's null-accepting behavior when its receiver is not a class or interface is unlikely to be a user dependency.

      Otherwise, all spec changes are clarification; there's no additional behavioral change.
      Show
      Class.isNestmateOf's null-accepting behavior when its receiver is not a class or interface is unlikely to be a user dependency. Otherwise, all spec changes are clarification; there's no additional behavioral change.
    • Java API
    • SE

      Summary

      Document the null argument (including null array component) handling of all core reflection APIs, which may accept nulls or reject nulls with different exceptions.

      Problem

      Core reflection APIs often have unclear null argument handling due to less professional standards back in older times. Issues about specifying null handling arises from time to time, such as JDK-8357658.

      Luckily, core reflection API surface is limited to java.lang.reflect and java.lang.Class. We can comprehensively check all public arguments in core reflection to ensure they have null handling explicitly specified.

      In the examination, I found that all of them without clear null argument handling specified have established consistent null behaviors, except for Class.isNestmateOf(Class), which returns false for int.class.isNestmateOf(null) but throws NullPointerException for Object.class.isNestmateOf(null).

      Solution

      We specify the null behavior for all APIs in core reflection, so that:

      1. All arguments that may be or contain null (as an array) are explicitly marked.
      2. All null rejection are now in the respective exception clauses, which is usually NullPointerException, and sometimes, IllegalArgumentException or NoSuchMethodException.

      For the only unclear null handling in Class::isNestmateOf, I propose to reject null consistently and eagerly to prevent potential errors.

      Specification

      In java.lang.Class:

      • forName(String): NPE for name
      • forName(String, boolean, ClassLoader): NPE for name, null ok for loader
      • isInstance(Object): null ok for argument
      • get[|Declared][Method|Constructor]: null ok for the parameter array; NoSuchMethodException for null as an array component
      • cast(Object): null ok for obj
      • asSubClass(Class): NPE for clazz
      • isNestmateOf(Class): NPE for c (only sometimes previously)

      In java.lang.reflect:

      • AccessibleObject.setAccessible: NPE for the array or its elements
        • Note: Behaviorally, this method may throw NPE after performing some side effect on some array elements. This is the longstanding behavior; its other exceptions thrown may also happen after some side effect has happened, and this details is not explicitly specified or noted.
      • Array.newInstance(Class, int[]): NPE for dimensions in addition to existing one for component class argument
      • Array.getLength(Object): NPE for argument
      • ClassFileFormatVersion.parse(Runtime.Version): NPE for argument
      • Proxy.newProxyInstance: null ok for ClassLoader
      • InaccessibleObjectException, InvocationTargetException, MalformedParametersException, UndeclaredThrowableException: null ok for all constructor args

      See the attached diff for the exact details.

        1. 8371954-0.patch
          15 kB
          Chen Liang
        2. 8371954-1.patch
          15 kB
          Chen Liang

            Assignee:
            Chen Liang
            Reporter:
            Chen Liang
            Alan Bateman
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: