Подтвердить что ты не робот

Java ищет метод с конкретной аннотацией и элементом аннотации

Предположим, что у меня есть этот класс аннотаций


@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(){ ... }
}

Итак, есть ли способ взглянуть на объект, "искать" метод с помощью аннотации @MethodXY, где его элемент x = 3, y = 2 и вызывать его?

Спасибо

4b9b3361

Ответ 1

Вот метод, который возвращает методы со специфическими аннотациями:

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;
}

Он может быть легко изменен в соответствии с вашими конкретными потребностями. Обратите внимание, что предоставленный метод пересекает иерархию классов, чтобы найти методы с требуемыми аннотациями.

Вот способ для ваших конкретных потребностей:

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;
}

Для вызова найденного метода (ов) pls ссылаются на tutorial. Одной из потенциальных трудностей здесь является количество аргументов метода, которые могут варьироваться между найденными методами и, следовательно, требуют некоторой дополнительной обработки.

Ответ 2

попробуйте этот пример кода:

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