-
Bug
-
Resolution: Fixed
-
P4
-
17, 20
-
b22
-
generic
-
generic
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8296599 | 19u-cpu | Srikanth Adayapalam | P4 | Resolved | Fixed | master |
JDK-8296021 | 19.0.2 | Srikanth Adayapalam | P4 | Resolved | Fixed | b04 |
JDK-8296020 | 17.0.7-oracle | Srikanth Adayapalam | P4 | Resolved | Fixed | b01 |
JDK-8299584 | 17.0.7 | Goetz Lindenmaier | P4 | Resolved | Fixed | b01 |
Distributor ID: Debian
Description: Debian GNU/Linux 11 (bullseye)
Release: 11
Codename: bullseye
----
Linux db 5.10.0-16-amd64 #1 SMP Debian 5.10.127-2 (2022-07-23) x86_64 GNU/Linux
A DESCRIPTION OF THE PROBLEM :
TYPE_USE annotations placed on generic type arguments of record components (e.g. List<@Annot String>) are for some reason discarded unless the record component type itself is annotated (e.g. @Annot List<@Annot String>).
I compiled the example program in the "Steps to Reproduce'' section with javac 17, 18, and 20ea and executed all three versions. They all printed the same result: an empty annotations array for the String type use. However, annotating the List type, too, and running the programs again now showed the result I expected: String being annotated with @Annot.
I also decompiled the class files via IntelliJ's decompiler: Interestingly, when the List was not annotated, the decompiled definition looked like:
public static record R(List<String> strings) {
public R(List<@Test.Annot String> strings) { this.strings = strings; }
public List<@Test.Annot String> strings() { return this.strings; }
}
while the annotated version contained the annotation at both places in the component definition:
public static record R(@Test.Annot List<@Test.Annot String> strings) {
public R(@Test.Annot List<@Test.Annot String> strings) {this.strings = strings;}
public @Test.Annot List<@Test.Annot String> strings() {return this.strings;}
}
I'm not sure whether this is actually a bug or simply not covered by the spec and, therefore, more of a feature request.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Write the following code and execute its main method:
package tmp;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Field;
import java.lang.reflect.RecordComponent;
import java.util.Arrays;
import java.util.List;
public final class Test {
@Target({ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Annot {}
public static final class C {
List<@Annot String> strings;
}
public record R(List<@Annot String> strings) {}
public static void main(String[] args) {
{
Field field = C.class.getDeclaredFields()[0];
AnnotatedParameterizedType type = (AnnotatedParameterizedType) field.getAnnotatedType();
AnnotatedType argument = type.getAnnotatedActualTypeArguments()[0];
System.out.println(Arrays.toString(argument.getAnnotations()));
}
{
RecordComponent component = R.class.getRecordComponents()[0];
AnnotatedParameterizedType type = (AnnotatedParameterizedType) component.getAnnotatedType();
AnnotatedType argument = type.getAnnotatedActualTypeArguments()[0];
System.out.println(Arrays.toString(argument.getAnnotations()));
}
}
}
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
[@tmp.Test$Annot()]
[@tmp.Test$Annot()]
ACTUAL -
[@tmp.Test$Annot()]
[]
CUSTOMER SUBMITTED WORKAROUND :
Instead of trying to access the annotation via the record component, you can access it via the field by using the same code used for class fields:
Field field = R.class.getDeclaredFields()[0];
...etc.
FREQUENCY : always
- backported by
-
JDK-8296020 TYPE_USE annotations on generic type arguments of record components discarded
-
- Resolved
-
-
JDK-8296021 TYPE_USE annotations on generic type arguments of record components discarded
-
- Resolved
-
-
JDK-8296599 TYPE_USE annotations on generic type arguments of record components discarded
-
- Resolved
-
-
JDK-8299584 TYPE_USE annotations on generic type arguments of record components discarded
-
- Resolved
-
- csr for
-
JDK-8295705 TYPE_USE annotations on generic type arguments of record components discarded
-
- Closed
-
- links to
-
Commit openjdk/jdk17u-dev/c9bbd558
-
Commit openjdk/jdk19u/c6e18499
-
Commit openjdk/jdk/4d9a1cd2
-
Review openjdk/jdk17u-dev/1022
-
Review openjdk/jdk19u/62
-
Review openjdk/jdk/10741