How to get TYPE_USE annotations on a generic bound

£可爱£侵袭症+ 提交于 2020-05-10 18:48:10

问题


I have this case:

public class SomeClass<T> {
    public <@A1 S extends @A2 T> @A3 S 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() 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)

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

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


回答1:


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

will print

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

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.

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.

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


来源:https://stackoverflow.com/questions/47175573/how-to-get-type-use-annotations-on-a-generic-bound

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!