Duplicate :
|
|
Relates :
|
|
Relates :
|
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.
|