Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java seek a method with specific annotation and its annotation element

Suppose I have this annotation 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?

Thanks

like image 321
nobody Avatar asked Jul 06 '11 08:07

nobody


People also ask

How do you check if a method has an annotation?

The isAnnotation() method is used to check whether a class object is an annotation. The isAnnotation() method has no parameters and returns a boolean value. If the return value is true , then the class object is an annotation. If the return value is false , then the class object is not an annotation.

What is @interface annotation in Java?

Annotation is defined like a ordinary Java interface, but with an '@' preceding the interface keyword (i.e., @interface ). You can declare methods inside an annotation definition (just like declaring abstract method inside an interface). These methods are called elements instead.

What is @target annotation in Java?

If an @Target meta-annotation is present, the compiler will enforce the usage restrictions indicated by ElementType enum constants, in line with JLS 9.7. 4. For example, this @Target meta-annotation indicates that the declared type is itself a meta-annotation type.


2 Answers

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 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(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.

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.

like image 128
01es Avatar answered Oct 19 '22 21:10

01es


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");         }     } } 
like image 22
dhblah Avatar answered Oct 19 '22 19:10

dhblah