为什么嵌套类型看不到generics类型参数的注释?

我没有得到以下代码的行为: https : //gist.github.com/tomaszalusky/3e3777b4fd0c6096f3f707bb19b50b52 – 请参阅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 { } Toplevel toplevel; Nested 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 { } 

编辑:实际结果是:

 field toplevel type=Toplevel annotatedType=sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl@1540e19d annotations=[@AnnotationOnTypeArgument$Anno()] type=class java.lang.Integer field nested type=AnnotationOnTypeArgument.AnnotationOnTypeArgument$Nested annotatedType=sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedTypeBaseImpl@677327b6 annotations=[] type=class java.lang.Integer 

当嵌套类型嵌套时,为什么类型参数上声明的注释数组为空? 我希望有一个元素就像顶级类型一样。 我很感激任何基于JLS的解释。

在JDK8u101( http://compilejava.net ),旧版JDK8和Eclipse上始终如一。

谢谢!

我给了一些时间进行调试,annotatedParameterizedType变量似乎仍然包含对于嵌套情况的allOnSameTargetTypeAnnotations字段中的Anno注释的引用

 annotatedParameterizedType = {AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl@539} type = {ParameterizedTypeImpl@540} "com.sample.Toplevel" decl = {Field@538} "com.sample.Toplevel com.sample.AnnotationOnTypeArgument.toplevel" location = {TypeAnnotation$LocationInfo@543} depth = 0 locations = {TypeAnnotation$LocationInfo$Location[0]@549} allOnSameTargetTypeAnnotations = {TypeAnnotation[1]@544} 0 = {TypeAnnotation@551} "@com.sample.AnnotationOnTypeArgument$Anno() with Targetnfo: FIELD: -2, -2 on base declaration: com.sample.Toplevel com.sample.AnnotationOnTypeArgument.toplevel" annotations = {LinkedHashMap@546} size = 0 

VS

 annotatedParameterizedType = {AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl@602} type = {ParameterizedTypeImpl@603} "com.sample.AnnotationOnTypeArgument.com.sample.AnnotationOnTypeArgument$Nested" decl = {Field@601} "com.sample.AnnotationOnTypeArgument$Nested com.sample.AnnotationOnTypeArgument.nested" location = {TypeAnnotation$LocationInfo@606} depth = 1 locations = {TypeAnnotation$LocationInfo$Location[1]@611} allOnSameTargetTypeAnnotations = {TypeAnnotation[1]@607} 0 = {TypeAnnotation@612} "@com.sample.AnnotationOnTypeArgument$Anno() with Targetnfo: FIELD: -2, -2 on base declaration: com.sample.AnnotationOnTypeArgument$Nested com.sample.AnnotationOnTypeArgument.nested" annotations = {LinkedHashMap@608} size = 0 

但是位置深度存在差异,AnnotatedTypeFactory的即将到来的getAnnotatedActualTypeArguments()方法包含一个TypeAnnotation.isSameLocationInfo()比较,作为向注释图添加元素的前提条件,在嵌套的情况下将变为false,因此最终没有元素正在增加

我也没有发现任何文件。 也许你在这里找到了一个问题

这是OpenJDK中的一个错误,我刚刚报道了这个错误,我希望它能够修复。 类型注释在实践中并没有真正使用,它似乎不是优先考虑的事情。 正如Holger所提到的,这是AnnotatedTypeFactory实现中的混合。

您可以使用Byte Buddy正确解析类文件元数据:

 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()); } 

这为您提供了预期的输出:

 field toplevel type=net.bytebuddy.Toplevel annotations=class java.lang.Integer type=[@net.bytebuddy.AnnotationOnTypeArgument$Anno()] field nested type=net.bytebuddy.AnnotationOnTypeArgument.net.bytebuddy.AnnotationOnTypeArgument$Nested annotations=class java.lang.Integer type=[@net.bytebuddy.AnnotationOnTypeArgument$Anno()]