Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8225470

Constructor.getParameterAnnotations does not include implicit enclosing param

    XMLWordPrintable

    Details

      Description

      ADDITIONAL SYSTEM INFORMATION :
      $ uname -a
      Linux job 4.18.0-20-generic #21~18.04.1-Ubuntu SMP Wed May 8 08:43:37 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
      $ java -version ~
      openjdk version "1.8.0_212"
      OpenJDK Runtime Environment (build 1.8.0_212-8u212-b03-0ubuntu1.18.04.1-b03)
      OpenJDK 64-Bit Server VM (build 25.212-b03, mixed mode)


      A DESCRIPTION OF THE PROBLEM :
      Javadoc for Executable#getParameterAnnotations states that "Synthetic and mandated parameters (see explanation below), such as the outer "this" parameter to an inner class constructor will be represented in the returned array."
      This is not true for the Constructor implementation.

      And it breaks the Parameter.getDeclaredAnnotations call - it returns annotations of the next parameter and fails with index error on last parameter.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile and run the provided source code

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      annotations = []
      annotations = []
      annotations = [@Scratch$Ann()]


      parameter = Scratch arg0
      parameter.getDeclaredAnnotations() = []

      parameter = java.lang.String arg1
      parameter.getDeclaredAnnotations() = []

      parameter = java.lang.String arg2
      parameter.getDeclaredAnnotations() = [@Scratch$Ann()]

      ACTUAL -
      annotations = []
      annotations = [@Scratch$Ann()]


      parameter = Scratch arg0
      parameter.getDeclaredAnnotations() = []

      parameter = java.lang.String arg1
      parameter.getDeclaredAnnotations() = [@Scratch$Ann()]

      parameter = java.lang.String arg2
      Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
      at java.lang.reflect.Parameter.getDeclaredAnnotations(Parameter.java:305)
      at Scratch.test(scratch_1.java:31)
      at Scratch.main(scratch_1.java:8)

      ---------- BEGIN SOURCE ----------
      import java.lang.annotation.*;
      import java.lang.reflect.Constructor;
      import java.lang.reflect.Parameter;
      import java.util.Arrays;

      class Scratch {
      public static void main(String[] args) {
      new Scratch().test();
      }

      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.PARAMETER)
      @interface Ann {}

      class Test {
      Test(String first, @Ann String second) {}
      }

      public void test() {

      Constructor<?> constructor = Test.class.getDeclaredConstructors()[0];

      for (Annotation[] annotations : constructor.getParameterAnnotations()) {
      System.out.println("annotations = " + Arrays.toString(annotations));
      }

      System.out.println("\n");

      for (Parameter parameter : constructor.getParameters()) {
      System.out.println("parameter = " + parameter);
      System.out.println("parameter.getDeclaredAnnotations() = " + Arrays.toString(parameter.getDeclaredAnnotations()));
      System.out.println();
      }
      }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      When working with Parameter arrays you can check if `parameter.getDeclaringExecutable().getDeclaringClass().getEnclosingClass() != null` and get annotations 'from previous parameter' accordingly.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              fmatte Fairoz Matte
              Reporter:
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: