-
Bug
-
Resolution: Duplicate
-
P4
-
8, 9, 10, 11, 12, 13, 14, 15
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.
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.
- duplicates
-
JDK-8263763 Synthetic constructor parameters of enum are not considered for annotation indices
-
- Resolved
-
- relates to
-
JDK-8180892 Correct handling of annotations on parameters
-
- Open
-
-
JDK-8262807 Note assumptions of core reflection modeling and parameter handling
-
- Resolved
-