Document null handling in core reflection APIs

XMLWordPrintable

    • Type: CSR
    • Resolution: Approved
    • 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, and change Class::isNestmateOf to be consistently null hostile in spec and implementation.

      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 primitive type, void, or array class receivers like int.class.isNestmateOf(null), but throws NullPointerException for class or interface receivers, like 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.

      Make APIs in class reject null or arrays containing null by default, and explicitly specify custom null behaviors (acceptance or rejection with different exception) on each API instead.

      For the only inconsistent null handling in Class::isNestmateOf, I propose to reject null consistently and eagerly so users don't run into new errors when a call site of this method suddenly starts to accept classes and interfaces.

      Specification

      In java.lang.Class:

      • NPE by default for all arguments, unless otherwise specified
      • Removed all existing explicit throws NPE clauses
      • forName(String, boolean, ClassLoader): 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

      Class::isNestmateOf(Class) has no spec update, but it is now consistently throwing NPE instead of only when c represents a class or interface.

      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
        2. 8371954-1.patch
          15 kB
        3. 8371954-2.patch
          18 kB

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

              Created:
              Updated:
              Resolved: