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

java.lang.reflect.Parameter.getAnnotation doesn't take into account synthetic parameters

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • 17
    • 8, 9, 10, 11, 12, 13, 14, 15
    • core-libs

      Sometimes synthetic parameters are added to the constructor (e.g. enum constructor). In this case, Parameter.getAnnotation doesn't take this into account. E.g. consider the following program:

      import java.lang.annotation.*;
      import java.lang.reflect.*;
      import java.util.Arrays;

      enum MyEnum {
        A(0.0, 0, "");

        MyEnum(@Foo("double annotated") double d,
               int i,
               @Foo("string annotated") String s) { }

        @Retention(RetentionPolicy.RUNTIME)
        @interface Foo {String value();}

        public static void main(String[] args) {
          Constructor<?> constructor = MyEnum.class.getDeclaredConstructors()[0];
          Parameter[] parameters = constructor.getParameters();
          Arrays.stream(parameters)
              .filter(p -> p.getType() == double.class)
              .forEach(p -> System.out.println(p.getAnnotation(Foo.class).value()));
        }
      }

      Expected output:

      double annotated

      Actual output:

      string annotated

      That's because compiler adds two synthetic parameters (enum constant name and ordinal), but RuntimeVisibleParameterAnnotations are not shifted by two (looks like it's specified so, by JVMS 4.7.18), and Parameter.getAnnotation doesn't take into account this shift either, so it reads the annotation of the wrong parameter.

            darcy Joe Darcy
            tvaleev Tagir Valeev
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: