为什么泛型类型参数的注释对于嵌套类型不可见? [英] Why annotation on generic type argument is not visible for nested type?
问题描述
我没有得到以下代码的行为:https://gist.github.com/tomaszalusky/3e3777b4fd0c6096f3f70c6096f3f707bb19b50b52"
I don't get the behaviour of following code: https://gist.github.com/tomaszalusky/3e3777b4fd0c6096f3f707bb19b50b52 - see embedded:
import java.lang.reflect.*;
import java.util.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class AnnotationOnTypeArgument {
@Target({ElementType.FIELD,ElementType.PARAMETER,ElementType.METHOD,ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Anno {
}
interface Nested<T> {
}
Toplevel<@Anno Integer> toplevel;
Nested<@Anno Integer> nested;
public static void main(String[] args) throws Exception {
print(AnnotationOnTypeArgument.class.getDeclaredField("toplevel"));
print(AnnotationOnTypeArgument.class.getDeclaredField("nested"));
}
private static void print(Field field) {
AnnotatedType annotatedType = field.getAnnotatedType();
AnnotatedParameterizedType annotatedParameterizedType = (AnnotatedParameterizedType)annotatedType;
ParameterizedType parameterizedType = (ParameterizedType)annotatedParameterizedType.getType();
AnnotatedType argType = annotatedParameterizedType.getAnnotatedActualTypeArguments()[0];
System.out.printf("field %s%ntype=%s%nannotatedType=%s%nannotations=%s%ntype=%s%n%n",
field.getName(), parameterizedType, argType, Arrays.asList(argType.getDeclaredAnnotations()), argType.getType());
}
}
interface Toplevel<T> {
}
实际结果是:
field toplevel
type=Toplevel<java.lang.Integer>
annotatedType=sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl@1540e19d
annotations=[@AnnotationOnTypeArgument$Anno()]
type=class java.lang.Integer
field nested
type=AnnotationOnTypeArgument.AnnotationOnTypeArgument$Nested<java.lang.Integer>
annotatedType=sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl@677327b6
annotations=[]
type=class java.lang.Integer
当周围类型嵌套时,为什么类型参数上声明的注释数组为空?我希望像顶级类型一样有一个元素.我将不胜感激任何基于 JLS 的解释.
Why the array of declared annotations on type argument is empty when surrounding type is nested? I expect to have one element just as for top level type. I would appreciate any explanation based on JLS.
在 JDK8u101 (http://compilejava.net)、较旧的 JDK8 和 Eclipse 上一致发生.
Happens consistently on JDK8u101 (http://compilejava.net), older JDK8 and Eclipse.
谢谢!
推荐答案
这是 OpenJDK 中的一个错误,我已经报告了一段时间,希望能够修复.类型注释在实践中并没有真正使用那么多,它似乎不是一个优先事项.正如 Holger 所提到的,这是 AnnotatedTypeFactory
实现中的一个混淆.
This is a bug in the OpenJDK, I have reported this a while ago and I hope it to be fixed. Type annotations are not really used that much in practice and it does not seem a priority. As Holger mentioned, this is a mixup in the implementation of the AnnotatedTypeFactory
.
您可以使用 Byte Buddy 来正确解析类文件元数据:
You can use Byte Buddy which parses the class file meta data correctly:
public static void main(String[] args) throws Exception {
TypeDescription type = TypePool.Default.ofClassPath()
.describe(AnnotationOnTypeArgument.class.getName())
.resolve();
print(type.getDeclaredFields().filter(named("toplevel")).getOnly());
print(type.getDeclaredFields().filter(named("nested")).getOnly());
}
private static void print(FieldDescription field) {
System.out.printf("field %s%ntype=%s%nannotations=%s%ntype=%s%n%n",
field.getName(),
field.getType(),
field.getType().getTypeArguments().get(0),
field.getType().getTypeArguments().get(0).getDeclaredAnnotations());
}
这为您提供了预期的输出:
This gives you the expected output:
field toplevel
type=net.bytebuddy.Toplevel<java.lang.Integer>
annotations=class java.lang.Integer
type=[@net.bytebuddy.AnnotationOnTypeArgument$Anno()]
field nested
type=net.bytebuddy.AnnotationOnTypeArgument.net.bytebuddy.AnnotationOnTypeArgument$Nested<java.lang.Integer>
annotations=class java.lang.Integer
type=[@net.bytebuddy.AnnotationOnTypeArgument$Anno()]
这篇关于为什么泛型类型参数的注释对于嵌套类型不可见?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!