2010-02-10 12 views
10

Zacząłem "dla zabawy, nikt nie wie, nikt nie dba" projektu open source (LinkSet).Czy istnieje skuteczniejszy sposób uzyskania metody z adnotacjami?

W jednym miejscu muszę uzyskać opatrzoną adnotacją metodę klasy.

Czy jest to skuteczniejszy sposób niż to? Mam na myśli bez potrzeby powtarzania każdej metody?

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

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

Jeśli chcesz tylko wiedzieć, czy metoda ma adnotacji i nie dbają o treści adnotacji można nazwać 'method.isAnnotationPresent (HandlerMethod.class)' –

Odpowiedz

1

Nie. Ale to wcale nie jest nieefektywne.

Na przykład sprężyny jest za pomocą następującego kodu:

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

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

(gdzie BridgedMethodResolver jest inny temat, ale to tylko zwraca Method Object)

Również zamiast porównując do null, można sprawdzić, czy adnotacja jest obecna z isAnnotationPresent(YourAnnotation.class) (jak zasugerowano w komentarzach poniżej pytania)

+0

No to jest coś takiego jak O (m * (1 + a)) gdzie m = liczba metod i a = średnia liczba adnotacji na metodę. a jest często bliskie 0, więc w rzeczywistości jest O (m). Coś takiego jak O (log (m)) byłoby lepsze, gdyby ten kod był często wywoływany. –

+0

i 'm' jest rzadko więcej niż 10;) – Bozho

+0

hmm - dobry punkt :) –

1

Jeśli masz zamiar wykonać kilka połączeń do tego dla każdej klasy możesz stworzyć deskryptor taki jak klasa, który nie robi niczego poza buforowaniem tego typu informacji. Następnie, gdy chcesz odzyskać informacje, wystarczy spojrzeć na jego deskryptor.

Aby odpowiedzieć na to pytanie:

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

zwróci wszystkie adnotacje z klasy. To, co zrobiłeś, zwróci tylko pierwszą adnotację metody. Podobnie jak:

Annotion[] annos = myMethod.getAnnotations(); 

zwraca wszystkie adnotacje danej metody.

+0

to nie zwróci tylko adnotacji klasowych ? metody te nie zostaną uwzględnione, a on ich interesuje – Bozho

+0

są już buforowane w obiekcie 'Method' - używa mapy – Bozho

+0

Tak, ale musisz użyć refleksji za każdym razem, kiedy chcesz.To, co mówię, to raz dostać się do tej mapy i nigdy więcej nie poddać się refleksji. – wheaties

12

Poszukaj Reflections (zależności: Guava i Javassist). Jest to biblioteka, która zoptymalizowała już większość z tego wszystkiego. Jest Reflections#getMethodsAnnotatedWith(), który odpowiada Twoim wymaganiom funkcjonalnym.

Oto SSCCE, wystarczy skopiować i wkleić.

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

} 
Powiązane problemy