本文介绍了如何在通用范围上获取TYPE_USE批注的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我有这种情况:

public class SomeClass<T> {
    public <@A1 S extends @A2 T> @A3 S myMethod() { ...}
}

并且我正在尝试在绑定的T上获取@A2批注.
假设myMethodSomeClass.class.getDeclaredMethod("myMethod"),这就是我所看到的.删除类型强制转换以提高可读性.

and I'm trying to get the @A2 annotation on the bound T.
This is what I'm seeing, assuming myMethod is SomeClass.class.getDeclaredMethod("myMethod"). Type casts removed for readability.

  • myMethod.getGenericReturnType().getAnnotations()返回@A1(我想是预期的)
  • myMethod.getGenericReturnType().getBounds()[0].getAnnotations()不返回 (不是@A2 ???)
  • myMethod.getAnnotatedReturnType().getAnnotations()返回@A3(我想是预期的)
  • myMethod.getAnnotatedReturnType().getAnnotatedBounds()[0].getAnnotations()不返回 (我想是例外)
  • myMethod.getGenericReturnType().getAnnotations() returns @A1 (as expected, I guess)
  • myMethod.getGenericReturnType().getBounds()[0].getAnnotations() returns nothing (?? shoudn't it be @A2 ??)
  • myMethod.getAnnotatedReturnType().getAnnotations() returns @A3 (as expected, I guess)
  • myMethod.getAnnotatedReturnType().getAnnotatedBounds()[0].getAnnotations() returns nothing (as excepted, I guess)

似乎@A2迷路了...听起来不明智.我是在做错什么,还是这确实是一些奇怪的行为?

It seems like @A2 got lost... and that doesn't sound sensible. Am I doing something wrong or is this indeed some bizarre behavior?

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

UPDATE:It is indeed a JDK bug, which I reported and it got accepted as JDK-8191466

推荐答案

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

All type annotations can be retrieved through the AnnotatedType hierarchy, except for the TypeVariable, whose annotations can be retrieve through AnnotatedTypeVariable.getType() which will be an instance of TypeVariable which extends AnnotatedElement now and happens to be identical with the object returned by Method.getGenericReturnType().

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

So you can retrieve all information, e.g.

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).

When your invocation of ((AnnotatedTypeVariable)myMethod.getAnnotatedReturnType()) .getAnnotatedBounds()[0].getAnnotations() does not provide @A2, you should recheck that A2 truly has @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE_USE).

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

Of course, that’s the "simplified" version handling only your specific method.

要处理所有可能的情况,您将需要更多的instanceof来处理TypeAnnotatedType的这些离散类型层次结构,尤其是在处理带注释的参数化类型和带注释的泛型数组类型时.

To handle all possible cases, you will need much more instanceofs, dealing with these disjunct type hierarchies of Type and AnnotatedType, especially when processing annotated parameterized types and annotated generic array types.

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

As said, TypeVariable is different, as it extends AnnotatedElement and also has the getAnnotatedBounds() method. So in this specific case, an alternative way to process the method is

List<TypeVariable<?>> typeParameters = Arrays.asList(myMethod.getTypeParameters());

for (TypeVariable<?> tv: typeParameters) {
    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());

这篇关于如何在通用范围上获取TYPE_USE批注的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-09 01:21