如何在Java Annotation Processing中获取字段的类型注释?

时间:2014-07-08 00:20:27

标签: java annotations preprocessor annotation-processing

例如,我有这段代码:

@Retention(RetentionPolicy.SOURCE)
public @interface ClassAnnotation {
}

@ClassAnnotation
public class AnnotatedClass {
}

@ClassAnnotation
public class AnotherAnnotatedClass {

    private AnnotatedClass someField;
    private int intIsNotAnnotated;
}

这个处理器在编译时预处理它:

@SupportedAnnotationTypes({ "com.example.ClassAnnotation" })
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class AwesomeProcessor extends AbstractProcessor {

    public boolean process(Set<? extends TypeElement> annotations,
            RoundEnvironment roundEnv) {
        // Skipped for brevity...
        // For each annotated class
        for (Element e : roundEnv.getElementsAnnotatedWith(ClassAnnotation.class)) {
            // Skipped for brevity...
            // For each field
            for (Element ee : classElement.getEnclosedElements()) {
                // Skipped for brevity... (of course there's kind checking)
                TypeMirror fieldType = fieldElement.asType();
                TypeElement fieldTypeElement = (TypeElement) processingEnv.
                    getTypeUtils().asElement(fieldType);
            }
        }
        // Skipped for brevity
    }
}

我需要检查字段的类型是否是用我的注释注释的类。不知何故,我有一个名为TypeElement的{​​{1}},它可能代表来自fieldTypeElement的{​​{1}}或AnnotatedClass来自someField的示例。如何获得int intIsNotAnnotated的{​​{1}}?我尝试了@ClassAnnotationAnnotatedClass,但它分别返回null和空列表。

2 个答案:

答案 0 :(得分:5)

我认为你在某种程度上得到了错误的TypeElement但不幸的是,部分代码丢失了。

这个简单的例子按预期工作:

processingEnv.getElementUtils().getTypeElement("AnnotatedClass").getAnnotationMirrors()

包含@ClassAnnotation

要获得字段的TypeElement,您必须

  1. 获取字段的类型
  2. 将类型转换为DeclaredType
  3. 获取声明类型的元素
  4. 将元素投射到TypeElement
  5. 尽管获取元素的注释,但最后一步并不是必需的:

    Element field = // ... 
    List<? extends AnnotationMirror> annotationMirrors =
        ((DeclaredType) field.asType()).asElement().getAnnotationMirrors();
    

    更新后的代码应该可以使用,我已经测试过了,运行正常。错误必须在其他地方。还需要检查一些其他事项:

    • 确保构建良好,有时构建步骤失败,旧代码未被注意
    • 检查注释的RetentionPolicy。无,CLASSRUNTIME都可以,但SOURCE无效

答案 1 :(得分:-1)

遍历Field上的Class并检查每个字段的类型是否包含注释。要获取Field的类型,请使用Field#getType方法。从提供的伪代码看,您可以访问Field

<强> Processor.java

public class Processor {

    public static void main(String[] args) {

        Class<?> clazz = AnotherAnnotatedClass.class;
        Field[] fields = clazz.getDeclaredFields();

        for(Field f:fields){
            if(f.getType().isAnnotationPresent(ClassAnnotation.class)){
                System.out.println(f.getName());
            }
        }
    }
}

<强> ClassAnnotation.java

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ClassAnnotation {

}

<强> AnnotatedClass.java

@ClassAnnotation
public class AnnotatedClass {

}

<强> AnotherAnnotatedClass.java

@ClassAnnotation
public class AnotherAnnotatedClass {

    private AnnotatedClass annotatedClass;
    private int intIsNotAnnotated;
}