2013-09-18 3 views
0

У меня есть 3 разных пользовательских аннотации. Предположим, что это Annotation1, Annotation2, Annotation3.Лучший способ обработки аннотаций

Я применил эти 3 аннотации к некоторым полям в своем классе. Теперь я извлекаю/получаю все поля, которым назначаются эти 3 аннотации. Так что я написал метод, как

public List<Field> getAnnotation1Fields(Annotation1 argAnnotation1){ 
    // Code to extract those fields... 
} 

Так что для моих 3 аннотаций мне нужно написать 3 различные методы, как

public List<Field> getAnnotation2Fields(Annotation2 argAnnotation2){ 
    // Code to extract those fields... 
} 

public List<Field> getAnnotation3Fields(Annotation3 argAnnotation3){ 
    // Code to extract those fields... 
} 

В приведенных выше методах логика извлечения такой же, но тип параметра отличается (Аргумент). Здесь мой вопрос: как я могу назвать эти три метода одной аннотацией ...? Так что один общий метод можно вызвать для любого типа аннотации (включая наши пользовательские аннотации).

+0

Вы передаете аннотацию этому методу или * тип аннотации *? – Holger

ответ

0

использовать метод Дженерик - Вы можете определить переменную параметр типа для методов, а также классы, например, так:

public <T> List<Field> getAnnotationFields(T argAnnotation) { 
    // Get fields with annotation type T 
} 

И тогда вы можете назвать это так же легко, как:

Annotation3 thingy = ...; 
getAnnotationFields(thingy); // Extracts fields for Annotation3 
+0

'' – Holger

+0

Здесь я использую пользовательские аннотации. Моя пользовательская аннотация содержит 2 переменные. При извлечении этих полей мне нужно получить доступ к этим переменным. Так что для этого мне нужно, чтобы TypeCast с моей пользовательской аннотации правильно ...? Так getAnnotationFields (T argAnnotation) Мне нужно ввести cast в CustomAnn = (CustomAnn) argAnnotation; как это. Как я могу избежать шага выбора этого типа, а также получить доступ к этим переменным. Так есть ли способ достичь этого ...? – Amar

+0

@Amar: Вы сказали, что логика извлечения всегда одна и та же, другими словами, не зависит от вашего типа аннотации. Вы смешиваете извлечение аннотированных элементов и используете значения аннотации? – Holger

0

public List<Field> getAnnotatedFields(java.lang.annotation.Annotation annotation)

или

public List<Field> getAnnotatedFields(Class<? extends Annotation> annotationType)

в зависимости от того, какой у вас экземпляр (первый) или тип (второй).

0

Вы можете сделать это с помощью этого простого метода: например

import java.lang.annotation.Annotation; 
import java.lang.reflect.Field; 

public static List<Field> getAnnotatedFields(Class<?> clazz, Class<? extends Annotation> annotationType) { 
    Field[] declaredFields = clazz.getDeclaredFields(); 
    List<Field> annotatedFields = new LinkedList<>(); 
    for(Field field : declaredFields) { 
     if(field.getAnnotation(annotationType) != null) 
      annotatedFields.add(field); 
    } 
    return annotatedFields; 
} 

Использование:

getAnnotatedFields(TestClass.class, Deprecated.class); 
+0

Hay Thanq, Но вместе с этим мне нужна дополнительная информация.Здесь я строю две карты, одна из которых - AnnotationsVsField (здесь поле является полем отражения java), а второе - моей аннотацией, имеет переменную типа «тип». Здесь моя вторая карта - FieldNameVsType. Итак, для построения второй карты нам нужны переменные типа «type» для этого, мне нужно набирать cast с соответствующей аннотацией вправо ...? С помощью вышеуказанного метода, как я могу достичь этой функции ...? – Amar

0

Я надеюсь, что ближе к вашим потребностям:

static <A extends Annotation> Map<String,A> getField2Annotation(
    Class<?> declaringClass, Class<A> annotationType) { 

    Field[] fields=declaringClass.getDeclaredFields(); 
    Map<String, A> map=Collections.emptyMap(); 
    for(Field f:fields) { 
    A anno=f.getAnnotation(annotationType); 
    if(anno!=null) { 
     if(map.isEmpty()) map=new HashMap<String, A>(); 
     map.put(f.getName(), anno); 
    } 
    } 
    return map; 
} 

Затем вы можете сделать что-то например:

public class Example { 
    @Retention(RetentionPolicy.RUNTIME) 
    @interface Foo { String value() default "bar"; } 

    @Foo static String X; 
    @Foo("baz") String Y; 

    public static void main(String[] args) { 
    Map<String, Foo> map = getField2Annotation(Example.class, Foo.class); 
    for(Map.Entry<String,Foo> e:map.entrySet()) { 
     System.out.println(e.getKey()+": "+e.getValue().value()); 
    } 
    } 
} 
Смежные вопросы