如何在泛型边界上获取TYPE_USE注释

kaq*_*qao 5 java generics reflection annotations java-8

我有这个案子:

public class SomeClass<T> {
    public <@A1 S extends @A2 T> @A3 S myMethod() { ...}
}
Run Code Online (Sandbox Code Playgroud)

而我正试图@A2在界限上得到注释T.
这就是我所看到的,假设myMethodSomeClass.class.getDeclaredMethod("myMethod").为了便于阅读,删除了类型转换.

  • myMethod.getGenericReturnType().getAnnotations()返回@A1(正如预期的那样,我猜)
  • myMethod.getGenericReturnType().getBounds()[0].getAnnotations()没有回报(??不是@A2吗?)
  • myMethod.getAnnotatedReturnType().getAnnotations()返回@A3(正如预期的那样,我猜)
  • myMethod.getAnnotatedReturnType().getAnnotatedBounds()[0].getAnnotations()什么都不返回(我猜是例外)

它似乎@A2迷路了......这听起来不合理.我做错了什么或这确实是一些奇怪的行为?

更新:这确实是一个JDK错误,我报告并且它被接受为JDK-8191466

Hol*_*ger 4

所有类型注释都可以通过层次结构检索AnnotatedType,除了TypeVariable,它的注释可以通过它检索AnnotatedTypeVariable.getType(),该实例现在TypeVariable扩展AnnotatedElement并且恰好与 所返回的对象相同Method.getGenericReturnType()

\n\n

这样您就可以检索所有信息,例如

\n\n
AnnotatedType art = myMethod.getAnnotatedReturnType();\nSystem.out.print(\n    Arrays.toString(art.getAnnotations())+" "+art.getType().getTypeName()+" -> ");\nfinal boolean typeVariable = art instanceof AnnotatedTypeVariable;\nif (typeVariable) System.out.print(\'<\');\nSystem.out.print(Arrays.toString(((AnnotatedElement)art.getType()).getAnnotations()) + " ");\nSystem.out.print(art.getType().getTypeName());\nif (typeVariable) {\n    AnnotatedTypeVariable atv = (AnnotatedTypeVariable)art;\n    AnnotatedType[] annotatedBounds = atv.getAnnotatedBounds();\n    if (annotatedBounds.length > 0) {\n        System.out.print(" extends ");\n        for (AnnotatedType aBound: annotatedBounds) {\n            System.out.print(Arrays.toString(aBound.getAnnotations()) + " ");\n            System.out.print(aBound.getType().getTypeName() + ", ");\n        }\n    }\n    System.out.println(">");\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

将打印

\n\n
AnnotatedType art = myMethod.getAnnotatedReturnType();\nSystem.out.print(\n    Arrays.toString(art.getAnnotations())+" "+art.getType().getTypeName()+" -> ");\nfinal boolean typeVariable = art instanceof AnnotatedTypeVariable;\nif (typeVariable) System.out.print(\'<\');\nSystem.out.print(Arrays.toString(((AnnotatedElement)art.getType()).getAnnotations()) + " ");\nSystem.out.print(art.getType().getTypeName());\nif (typeVariable) {\n    AnnotatedTypeVariable atv = (AnnotatedTypeVariable)art;\n    AnnotatedType[] annotatedBounds = atv.getAnnotatedBounds();\n    if (annotatedBounds.length > 0) {\n        System.out.print(" extends ");\n        for (AnnotatedType aBound: annotatedBounds) {\n            System.out.print(Arrays.toString(aBound.getAnnotations()) + " ");\n            System.out.print(aBound.getType().getTypeName() + ", ");\n        }\n    }\n    System.out.println(">");\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

当您的调用((AnnotatedTypeVariable)myMethod.getAnnotatedReturnType()) .getAnnotatedBounds()[0].getAnnotations()没有提供时@A2,您应该重新检查是否A2确实提供了@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE_USE)

\n\n

当然,\xe2\x80\x99s \xe2\x80\x9csimplified\xe2\x80\x9d 版本仅处理您的特定方法。

\n\n

为了处理所有可能的情况,您将需要更多的s 来处理和instanceof的这些分离类型层次结构,特别是在处理带注释的参数化类型和带注释的泛型数组类型时。TypeAnnotatedType

\n\n

正如所说,TypeVariable不同的是,它延伸AnnotatedElement也有getAnnotatedBounds()方法。因此,在这种特定情况下,处理该方法的另一种方法是

\n\n
List<TypeVariable<?>> typeParameters = Arrays.asList(myMethod.getTypeParameters());\n\nfor (TypeVariable<?> tv: typeParameters) {\n    System.out.print("< "+Arrays.toString(tv.getAnnotations())+" "+tv.getName());\n    AnnotatedType[] annotatedBounds = tv.getAnnotatedBounds();\n    if (annotatedBounds.length > 0) {\n        System.out.print(" extends ");\n        for (AnnotatedType aBound: annotatedBounds) {\n            System.out.print(Arrays.toString(aBound.getAnnotations()) + " ");\n            System.out.print(aBound.getType().getTypeName() + ", ");\n        }\n    }\n    System.out.print("> ");\n}\n\nAnnotatedType art = myMethod.getAnnotatedReturnType();\nSystem.out.print(Arrays.toString(art.getAnnotations()) + " ");\nint ix = typeParameters.indexOf(art.getType());\nif (ix >= 0) System.out.print("[ref to type parameter #" + ix + "] ");\nSystem.out.println(art.getType().getTypeName());\n
Run Code Online (Sandbox Code Playgroud)\n

  • 事实上,在这种情况下,即使递归应用“AnnotatedTypeVariable”处理也无济于事。注释似乎丢失了。 (2认同)
  • 至少,我可以验证该信息是否存在于已编译的类文件中。Java 9 没有表现出任何差异。 (2认同)