web-dev-qa-db-fra.com

Java recherche une méthode avec une annotation spécifique et son élément d'annotation

Supposons que j'ai cette classe d'annotation


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodXY {
    public int x();
    public int y();
}

public class AnnotationTest {
    @MethodXY(x=5, y=5)
    public void myMethodA(){ ... }

    @MethodXY(x=3, y=2)
    public void myMethodB(){ ... }
}

Existe-t-il donc un moyen d'examiner un objet, de "rechercher" la méthode avec l'annotation @MethodXY, où son élément x = 3, y = 2, et de l'invoquer?

Merci

36
nobody

Voici une méthode, qui renvoie des méthodes avec des annotations spécifiques:

public static List<Method> getMethodsAnnotatedWith(final Class<?> type, final Class<? extends Annotation> annotation) {
    final List<Method> methods = new ArrayList<Method>();
    Class<?> klass = type;
    while (klass != Object.class) { // need to iterated thought hierarchy in order to retrieve methods from above the current instance
        // iterate though the list of methods declared in the class represented by klass variable, and add those annotated with the specified annotation
        final List<Method> allMethods = new ArrayList<Method>(Arrays.asList(klass.getDeclaredMethods()));       
        for (final Method method : allMethods) {
            if (method.isAnnotationPresent(annotation)) {
                Annotation annotInstance = method.getAnnotation(annotation);
                // TODO process annotInstance
                methods.add(method);
            }
        }
        // move to the upper class in the hierarchy in search for more methods
        klass = klass.getSuperclass();
    }
    return methods;
}

Il peut être facilement modifié selon vos besoins spécifiques. Veuillez noter que la méthode fournie traverse la hiérarchie des classes afin de trouver des méthodes avec les annotations requises.

Voici une méthode pour vos besoins spécifiques:

public static List<Method> getMethodsAnnotatedWithMethodXY(final Class<?> type) {
    final List<Method> methods = new ArrayList<Method>();
    Class<?> klass = type;
    while (klass != Object.class) { // need to iterated thought hierarchy in order to retrieve methods from above the current instance
        // iterate though the list of methods declared in the class represented by klass variable, and add those annotated with the specified annotation
        final List<Method> allMethods = new ArrayList<Method>(Arrays.asList(klass.getDeclaredMethods()));
        for (final Method method : allMethods) {
            if (method.isAnnotationPresent(MethodXY.class)) {
                MethodXY annotInstance = method.getAnnotation(MethodXY.class);
                if (annotInstance.x() == 3 && annotInstance.y() == 2) {         
                    methods.add(method);
                }
            }
        }
        // move to the upper class in the hierarchy in search for more methods
        klass = klass.getSuperclass();
    }
    return methods;
}

Pour l'invocation de la ou des méthodes trouvées, veuillez consulter un tutoriel . L'une des difficultés potentielles ici est le nombre d'arguments de méthode, qui peuvent varier entre les méthodes trouvées et nécessitant ainsi un traitement supplémentaire.

62
01es

essayez cet exemple de code:

import Java.lang.annotation.Annotation;
import Java.lang.reflect.Method;
import Java.lang.annotation.Retention;
import Java.lang.annotation.RetentionPolicy;
import Java.lang.annotation.Target;
import Java.lang.annotation.ElementType;
import Java.lang.reflect.InvocationTargetException;

class AnotTest {
    public static void main(String... args) {
        AnnotationTest at = new AnnotationTest();
        for (Method m : at.getClass().getMethods()) {
           MethodXY mXY = (MethodXY)m.getAnnotation(MethodXY.class);
           if (mXY != null) {
               if (mXY.x() == 3 && mXY.y() == 2){
                   try {
                       m.invoke(at);
                   } catch (IllegalAccessException e) {
                       //do nothing;
                   } catch (InvocationTargetException o) {
                       //do nothing;
                   }
               }
           }
        }
    }
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    static public @interface MethodXY {
        public int x();
        public int y();
    }

    static class AnnotationTest {
        @MethodXY(x=5, y=5)
        public void myMethodA() {
            System.out.println("boo");
        }

        @MethodXY(x=3, y=2)
        public void myMethodB() {
            System.out.println("foo");
        }
    }
}
3
dhblah