2011-07-06 8 views
27

Supongamos que tengo esta clase de anotaciónJava buscan un método con anotación específica y su elemento de anotación


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

Entonces, ¿hay una manera de mirar a un objeto, "buscar" a cabo el método con la anotación @MethodXY, donde su elemento x = 3, y = 2, e invocarlo?

Gracias

Respuesta

45

Aquí es un método que devuelve métodos con anotaciones específicas:

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

Puede ser modificado fácilmente a sus necesidades específicas. Por favor tenga en cuenta que el método proporcionado atraviesa la jerarquía de clases para encontrar métodos con anotaciones requeridas.

Aquí es un método para sus necesidades específicas:

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

para la invocación del método (s) encontrado pls refieren una tutorial. Una de las posibles dificultades aquí es la cantidad de argumentos de métodos, que pueden variar entre los métodos encontrados y, por lo tanto, requieren algún procesamiento adicional.

+4

Supongo que cada ejemplo de código que he visto hasta ahora involucra a todos "exploración" todos los métodos – nobody

+0

Sólo una cabeza, anotación podría ser nula en la línea de anotación annotInstance = método. getAnnotation (anotación); – kliron

+0

@kliron Hay guard 'if (method.isAnnotationPresent (MethodXY.class)) ... '¿por qué' null'? – 01es

3

probar este ejemplo de código:

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

¿Podría explicar lo que ha hecho también? – tilaprimera

+1

@tilaprimera creando una nueva instancia de AnnotationTest, tomando todos los métodos de la clase de definición, iterando a través de métodos, en cada uno de ellos intentando obtener una anotación llamada 'MethodXY', si podemos obtenerla, entonces estamos comprobando qué' x' y 'y' valores que tiene, si son 3 y 2 respectivamente, estamos invocando ese método. – dhblah