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

我有这个案子:

public class SomeClass

而我正试图在绑定的T.上获得@ A2注释
这就是我所看到的,假设myMethod是SomeClass.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

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

因此,您可以检索所有信息,例如

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

将打印

[@A3()] S -> <[@A1()] S extends [@A2()] T,>

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

当然,这是仅处理您特定方法的“简化”版本.

要处理所有可能的情况,您将需要更多的instanceofs,处理Type和AnnotatedType的这些析取类型层次结构,尤其是在处理带注释的参数化类型和带注释的通用数组类型时.

如上所述,TypeVariable是不同的,因为它扩展了AnnotatedElement并且还具有getAnnotatedBounds()方法.因此,在这种特定情况下,处理该方法的另一种方法

Listarameters = Arrays.asList(myMethod.getTypeParameters());

for(TypeVariablearameters) {
    System.out.print("< "+Arrays.toString(tv.getAnnotations())+" "+tv.getName());
    AnnotatedType[] annotatedBounds = tv.getAnnotatedBounds();
    if(annotatedBounds.length > 0) {
        System.out.print(" extends ");
        for(AnnotatedType aBound: annotatedBounds) {
            System.out.print(Arrays.toString(aBound.getAnnotations())+" ");
            System.out.print(aBound.getType().getTypeName()+",");
        }
    }
    System.out.print("> ");
}

AnnotatedType art = myMethod.getAnnotatedReturnType();
System.out.print(Arrays.toString(art.getAnnotations())+" ");
int ix = typeParameters.indexOf(art.getType());
if(ix >= 0) System.out.print("[ref to type parameter #"+ix+"] ");
System.out.println(art.getType().getTypeName());

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...