处理注释的最佳方法

时间:2013-09-18 07:01:35

标签: java

我有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...
}

在上述方法中,提取逻辑相同但参数类型不同(参数)。这里我的问题是如何在单个注释中调用这三种方法......?因此,可以为任何类型的注释调用一个常用方法(包括我们的自定义注释)。

4 个答案:

答案 0 :(得分:0)

使用方法泛型 - 您可以为方法和类定义变量类型参数,如下所示:

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

然后你可以像以下一样轻松地调用它:

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

答案 1 :(得分:0)

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

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

取决于您拥有的实例(第一个)或类型(第二个)。

答案 2 :(得分: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);

答案 3 :(得分: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());
    }
  }
}