How to get annotations in nested parameter parameter?

Yu Fang :

If I have a function like this,

public void park( List< @myNote("list") List< @myNote("integer") Integer>> l){ System.out.println("park"); }

If I use Parameter.getAnnotations() and Paramter.getDeclaredAnnotation, I can only get @myNote("list"). Are any ways to get the annotation @myNote("integer")?

This may be related to How to get all types of the inner structures of a nested type?

Andreas :

Here is code to print the annotations, so you can see where in the reflection API they can be found.

Basically, you call param.getAnnotatedType(), check if the AnnotatedType is an AnnotatedParameterizedType, and call getAnnotatedActualTypeArguments() to get the generic type arguments, and do that recursively.

For each AnnotatedType, top-level or nested, you call getDeclaredAnnotations() or getAnnotations() to get the annotations on that type.

I added extra stuff, just so you can see how it works.

public class Test {
    public static void main(String[] args) {
        Method method = Test.class.getDeclaredMethod("park", List.class, Map.class);
        for (Parameter param : method.getParameters()) {
            System.out.println("Parameter: " + param);
            printAnnotatedType(1, param.getAnnotatedType());
        }
    }
    static void printAnnotatedType(int indent, AnnotatedType type) {
        System.out.println("  ".repeat(indent) + "AnnotatedType: " + type);
        System.out.println("  ".repeat(indent + 2) + "Type: " + type.getType());
        for (Annotation annotation : type.getDeclaredAnnotations()) {
            System.out.println("  ".repeat(indent + 2) + "Annotation: " + annotation);
        }
        if (type instanceof AnnotatedParameterizedType) {
            AnnotatedParameterizedType pt = (AnnotatedParameterizedType) type;
            for (AnnotatedType typeArg : pt.getAnnotatedActualTypeArguments()) {
                printAnnotatedType(indent + 1, typeArg);
            }
        }
    }
    public void park(@myNote("p0") List< @myNote("list") List< @myNote("integer") @myOther Integer>> l,
                     @myNote("p1") Map< @myNote("key") Long, @myNote("value") String> m) {
        System.out.println("park");
    }
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@interface myNote {
    String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@interface myOther {
}

Output

Parameter: java.util.List<java.util.List<java.lang.Integer>> arg0
  AnnotatedType: @myNote(value="p0") java.util.List<@myNote(value="list") java.util.List<@myNote(value="integer") @myOther() java.lang.Integer>>
      Type: java.util.List<java.util.List<java.lang.Integer>>
      Annotation: @myNote(value="p0")
    AnnotatedType: @myNote(value="list") java.util.List<@myNote(value="integer") @myOther() java.lang.Integer>
        Type: java.util.List<java.lang.Integer>
        Annotation: @myNote(value="list")
      AnnotatedType: @myNote(value="integer") @myOther() java.lang.Integer
          Type: class java.lang.Integer
          Annotation: @myNote(value="integer")
          Annotation: @myOther()
Parameter: java.util.Map<java.lang.Long, java.lang.String> arg1
  AnnotatedType: @myNote(value="p1") java.util.Map<@myNote(value="key") java.lang.Long, @myNote(value="value") java.lang.String>
      Type: java.util.Map<java.lang.Long, java.lang.String>
      Annotation: @myNote(value="p1")
    AnnotatedType: @myNote(value="key") java.lang.Long
        Type: class java.lang.Long
        Annotation: @myNote(value="key")
    AnnotatedType: @myNote(value="value") java.lang.String
        Type: class java.lang.String
        Annotation: @myNote(value="value")

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=20869&siteId=1