2010-02-10 13 views
10

Comencé un proyecto de código abierto "por diversión, nadie sabe, a nadie le importa" (LinkSet).¿Existe alguna manera más eficiente de obtener un método anotado?

En un lugar necesito obtener un método anotado de una clase.

¿Hay una manera más eficiente de hacerlo que esto? Quiero decir sin la necesidad de iterar a través de todos los métodos?

for (final Method method : cls.getDeclaredMethods()) { 

    final HandlerMethod handler = method.getAnnotation(HandlerMethod.class); 
     if (handler != null) { 
       return method; 
      } 
     } 
+1

Si sólo desea saber si el método tiene la anotación y no se preocupan por el contenido de la anotación puede llamar 'method.isAnnotationPresent (HandlerMethod.class)' –

Respuesta

1

No. Pero esto no es ineficiente en absoluto.

Por ejemplo primavera está utilizando el siguiente código:

public static <A extends Annotation> A getAnnotation(
     Method method, Class<A> annotationType) { 

    return BridgeMethodResolver. 
     findBridgedMethod(method).getAnnotation(annotationType); 
} 

(donde el BridgedMethodResolver es otro tema, pero sólo devuelve un objeto Method)

También, en lugar de comparar a null, puede compruebe si hay una anotación presente en isAnnotationPresent(YourAnnotation.class) (como se sugiere en los comentarios debajo de la pregunta)

+0

Bueno, es algo así como O (m * (1 + a)) donde m = número de métodos y a = número promedio de anotaciones por método. a menudo está cerca de 0, por lo que en realidad es O (m). Algo como O (log (m)) sería mejor si este código se invoca con frecuencia. –

+0

y 'm' rara vez es más de 10;) – Bozho

+0

hmm - buen punto :) –

1

Si va a hacer varias llamadas a esto para cada clase puede crear un descriptor como clase que no hace más que almacenar en caché este tipo de información. Luego, cuando desee recuperar la información, simplemente mire su descriptor.

Para responder a su pregunta:

Class<?> _class = Whatever.class; 
Annotation[] annos = _class.getAnnotations(); 

volverá todas las anotaciones de una clase. Lo que has hecho solo devolverá la primera anotación de un método. Del mismo modo:

Annotion[] annos = myMethod.getAnnotations(); 

devuelve todas las anotaciones de un método determinado.

+0

no devolverá solo anotaciones de nivel de clase ? los métodos no se incluirán, y él está interesado en ellos – Bozho

+0

ya están almacenados en la memoria caché en el objeto 'Método'; está usando un mapa – Bozho

+0

Sí, pero debe usar el reflejo cada vez que lo desee.Lo que estoy diciendo es llegar a ese mapa una vez y nunca volver a reflexionar. – wheaties

12

Echa un vistazo a Reflections (dependencias: Guava y Javassist). Es una biblioteca que ya ha optimizado la mayor parte de todo. Hay un Reflections#getMethodsAnnotatedWith() que se adapta a sus necesidades funcionales.

Aquí hay SSCCE, solo copie y pase.

package com.stackoverflow; 

import java.lang.reflect.Method; 
import java.util.Set; 

import org.reflections.Reflections; 
import org.reflections.scanners.MethodAnnotationsScanner; 
import org.reflections.util.ClasspathHelper; 
import org.reflections.util.ConfigurationBuilder; 

public class Test { 

    @Deprecated 
    public static void main(String[] args) { 
     Reflections reflections = new Reflections(new ConfigurationBuilder() 
      .setUrls(ClasspathHelper.forPackage("com.stackoverflow")) 
      .setScanners(new MethodAnnotationsScanner())); 
     Set<Method> methods = reflections.getMethodsAnnotatedWith(Deprecated.class); 
     System.out.println(methods); 
    } 

} 
Cuestiones relacionadas