-
Bug
-
Resolution: Unresolved
-
P4
-
11, 25
-
generic
-
generic
ADDITIONAL SYSTEM INFORMATION :
Is reproducible in at least: 21.0.7, 24.0.1, 17.0.15
output of java --version:
openjdk 24.0.1 2025-04-15
OpenJDK Runtime Environment (build 24.0.1+11)
OpenJDK 64-Bit Server VM (build 24.0.1+11, mixed mode, sharing)
MacBook pro M1Max, 32GB, macOS 15.5
output of `uname -a:
Darwin MacBook-Pro-von-Axel.local 24.5.0 Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:49 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6000 arm64
A DESCRIPTION OF THE PROBLEM :
In attached sample code, the E constructor takes two parameters, the second of which is annotated with @Annotation that has target TYPE_USE. The compiler introduces two additional synthetic parameters for ordinal and name. If I query the annotations, the annotation is present on the second synthetic parameter instead of the second non-synthetic parameter.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Save the example code as Main.java, then run using `java Main`.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Constructor signature: private E(java.lang.String,int,int,java.lang.String)
Parameter count: 4
Parameter[0]: String arg0 - annotations: none
Parameter[1]: int arg1 - annotations: none
Parameter[2]: int arg2 - annotations: none
Parameter[3]: String arg3 - annotations:: @Annotation()
ACTUAL -
Constructor signature: private E(java.lang.String,int,int,java.lang.String)
Parameter count: 4
Parameter[0]: String arg0 - annotations: none
Parameter[1]: int arg1 - annotations: @Annotation()
Parameter[2]: int arg2 - annotations: none
Parameter[3]: String arg3 - annotations: none
---------- BEGIN SOURCE ----------
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Parameter;
public class Main {
public static void main(String[] args) throws Exception {
// Get the enum constructor
var constructor = E.class.getDeclaredConstructors()[0];
Parameter[] parameters = constructor.getParameters();
System.out.println("Constructor signature: " + constructor);
System.out.println("Parameter count: " + parameters.length);
for (int i = 0; i < parameters.length; i++) {
Parameter param = parameters[i];
var annotations = param.getAnnotatedType().getDeclaredAnnotations();
System.out.printf("Parameter[%d]: %s %s - annotations: %s%n",
i, param.getType().getSimpleName(), param.getName(),
annotations.length > 0 ? annotations[0] : "none");
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@interface Annotation {
}
enum E {
VALUE1(42, "hello"),
VALUE2(99, null);
E(int number, @Annotation String text) {
}
}
---------- END SOURCE ----------
Is reproducible in at least: 21.0.7, 24.0.1, 17.0.15
output of java --version:
openjdk 24.0.1 2025-04-15
OpenJDK Runtime Environment (build 24.0.1+11)
OpenJDK 64-Bit Server VM (build 24.0.1+11, mixed mode, sharing)
MacBook pro M1Max, 32GB, macOS 15.5
output of `uname -a:
Darwin MacBook-Pro-von-Axel.local 24.5.0 Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:49 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6000 arm64
A DESCRIPTION OF THE PROBLEM :
In attached sample code, the E constructor takes two parameters, the second of which is annotated with @Annotation that has target TYPE_USE. The compiler introduces two additional synthetic parameters for ordinal and name. If I query the annotations, the annotation is present on the second synthetic parameter instead of the second non-synthetic parameter.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Save the example code as Main.java, then run using `java Main`.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Constructor signature: private E(java.lang.String,int,int,java.lang.String)
Parameter count: 4
Parameter[0]: String arg0 - annotations: none
Parameter[1]: int arg1 - annotations: none
Parameter[2]: int arg2 - annotations: none
Parameter[3]: String arg3 - annotations:: @Annotation()
ACTUAL -
Constructor signature: private E(java.lang.String,int,int,java.lang.String)
Parameter count: 4
Parameter[0]: String arg0 - annotations: none
Parameter[1]: int arg1 - annotations: @Annotation()
Parameter[2]: int arg2 - annotations: none
Parameter[3]: String arg3 - annotations: none
---------- BEGIN SOURCE ----------
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Parameter;
public class Main {
public static void main(String[] args) throws Exception {
// Get the enum constructor
var constructor = E.class.getDeclaredConstructors()[0];
Parameter[] parameters = constructor.getParameters();
System.out.println("Constructor signature: " + constructor);
System.out.println("Parameter count: " + parameters.length);
for (int i = 0; i < parameters.length; i++) {
Parameter param = parameters[i];
var annotations = param.getAnnotatedType().getDeclaredAnnotations();
System.out.printf("Parameter[%d]: %s %s - annotations: %s%n",
i, param.getType().getSimpleName(), param.getName(),
annotations.length > 0 ? annotations[0] : "none");
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@interface Annotation {
}
enum E {
VALUE1(42, "hello"),
VALUE2(99, null);
E(int number, @Annotation String text) {
}
}
---------- END SOURCE ----------
- relates to
-
JDK-8180892 Correct handling of annotations on parameters
-
- Open
-