Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access an annotation on a generic type parameter of a method argument?

Assume I want to inspect the following class using reflection:

class Foo {
   void bar(List<@Important String> b) {}
}

Note that the @Important annotation is not on the argument itself (then I could use Method.getParameterAnnotations()), but on its type parameter (which is allowed when the annotation is declared to have ElementType.TYPE_USE).

Is there a way to read such annotations in Java 11?

like image 686
Landei Avatar asked Sep 17 '25 02:09

Landei


1 Answers

Unfortunately, this part of the Reflection API is horrible. The base types do not have the necessary query methods and there is no Visitor API or such alike. So any code trying to do a full introspection has no choice but to perform lots of instanceof checks, to handle all possible cases.

If you know beforehand that the method’s type should be a parameterized type and you only want to check the annotations of its first type argument, you can do it a bit simpler, ignoring all other possible cases:

import java.lang.annotation.*;
import java.lang.reflect.AnnotatedParameterizedType;
import java.lang.reflect.Method;
import java.util.*;

public class Main {
    public static void main(String[] args) throws NoSuchMethodException {
        Method m = Foo.class.getDeclaredMethod("bar", List.class);

        var at  = m.getAnnotatedParameterTypes()[0];
        var ata = ((AnnotatedParameterizedType)at).getAnnotatedActualTypeArguments()[0];

        // get all annotations
        for(var a: ata.getAnnotations()) {
            System.out.println(a);
        }

        // or check the presence of a known annotation
        System.out.println(ata.getAnnotation(Important.class) != null);
    }

    class Foo {
        void bar(List<@Important String> b) {}
    }
}

Demo on Ideone

@Important()
true
like image 163
Holger Avatar answered Sep 19 '25 18:09

Holger