简体   繁体   English

Java 求一个带有特定注解的方法及其注解元素

[英]Java seek a method with specific annotation and its annotation element

Suppose I have this annotation class假设我有这个注释 class


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

So is there a way to look into an object, "seek" out the method with the @MethodXY annotation, where its element x = 3, y = 2, and invoke it?那么有没有办法查看 object,“寻找”带有 @MethodXY 注释的方法,其中它的元素 x = 3,y = 2,然后调用它?

Thanks谢谢

Here is a method, which returns methods with specific annotations:这是一个方法,它返回带有特定注释的方法:

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 traverse a type hierarchy in order to process methods from super types
        // iterate though the list of methods declared in the class represented by klass variable, and add those annotated with the specified annotation
        for (final Method method : klass.getDeclaredMethods()) {
            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;
}

It can be easily modified to your specific needs.它可以根据您的特定需求轻松修改。 Pls note that the provided method traverses class hierarchy in order to find methods with required annotations.请注意,提供的方法遍历 class 层次结构,以便找到具有所需注释的方法。

Here is a method for your specific needs:这是满足您特定需求的方法:

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
        for (final Method method : klass.getDeclaredMethods()) {
            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;
}

For invocation of the found method(s) pls refer a tutorial .对于找到的方法的调用,请参考教程 One of the potential difficulties here is the number of method arguments, which could vary between found methods and thus requiring some additional processing.这里的潜在困难之一是方法 arguments 的数量,它可能因找到的方法而异,因此需要一些额外的处理。

try this code sample:试试这个代码示例:

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");
        }
    }
}
private static final Method getMethodByAnnotation(Class<?> cla, Class<? extends Annotation> annotation,
        int methodIndex) {
    Stream<Method> stream = Arrays.stream(cla.getDeclaredMethods())
            .filter(m -> m.isAnnotationPresent(annotation));
    return methodIndex == 0 ? stream.findFirst().get() : stream.toArray(Method[]::new)[methodIndex];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM