简体   繁体   English

如何在Java注释处理中获取字段的类型注释?

[英]How to get field's type annotation in Java Annotation Processing?

For example, I have this code: 例如,我有以下代码:

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

@ClassAnnotation
public class AnnotatedClass {
}

@ClassAnnotation
public class AnotherAnnotatedClass {

    private AnnotatedClass someField;
    private int intIsNotAnnotated;
}

And this processor to preprocess it in compile time: 并在编译时对该处理器进行预处理:

@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
    }
}

I need to check whether a field's type is a class that is annotated with my annotation. 我需要检查字段的类型是否是使用我的注释进行注释的类。 Somehow I've got a TypeElement named fieldTypeElement , it may represent AnnotatedClass from someField or int from intIsNotAnnotated in the example. 不知怎的,我已经有了一个TypeElement命名fieldTypeElement ,它可能代表AnnotatedClasssomeFieldintintIsNotAnnotated的例子。 How to get @ClassAnnotation of AnnotatedClass of someField ? 如何获取@ClassAnnotationAnnotatedClasssomeField I've tried fieldTypeElement.getAnnotation(ClassAnnotation.class) and fieldTypeElement.getAnnotationMirrors() , but it returns null and empty list respectively. 我尝试过fieldTypeElement.getAnnotation(ClassAnnotation.class)fieldTypeElement.getAnnotationMirrors() ,但是它分别返回null和空列表。

I think you are somehow getting the wrong TypeElement but unfortunatly that part of the code is missing. 我认为您以某种方式获取了错误的TypeElement但不幸的是,该部分代码丢失了。

This simple example works as expected: 这个简单的示例按预期工作:

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

contains @ClassAnnotation . 包含@ClassAnnotation

To get the TypeElement of a field, you'll have to 要获取字段的TypeElement ,您必须

  1. get the fields's type 获取字段的类型
  2. cast the type to DeclaredType 将类型转换为DeclaredType
  3. get the declared type's element 获取声明的类型的元素
  4. cast the element to TypeElement 将元素转换为TypeElement

The last step isn't necessary though to get an element's annotations: 尽管不需要获取元素的注释,但最后一步不是必需的:

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

The updated code should work, I've tested it and it runs fine. 更新的代码应该可以运行,我已经对其进行了测试,并且运行良好。 The error must be elsewhere. 该错误必须在其他地方。 Some other things to check for: 其他要检查的内容:

  • Make sure the build is good, sometimes a build step fails and old code is used unnoticed 确保构建良好,有时构建步骤失败并且未注意到使用旧代码
  • Check the RetentionPolicy of the annotation. 检查注释的RetentionPolicy None, CLASS or RUNTIME are fine but SOURCE won't work 无, CLASSRUNTIME都可以,但是SOURCE无法正常工作

Iterate through the Field s on the Class and check whether the type of each field contains the annotation. 遍历Class上的Field ,并检查每个字段的类型是否包含注释。 To get the type of the Field use the Field#getType method. 若要获取Field的类型,请使用Field#getType方法。 From the provided pseudo code it appears you have access to the Field s. 从提供的伪代码看来,您可以访问Field

Processor.java 处理器.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 ClassAnnotation.java

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

}

AnnotatedClass.java AnnotatedClass.java

@ClassAnnotation
public class AnnotatedClass {

}

AnotherAnnotatedClass.java AnotherAnnotatedClass.java

@ClassAnnotation
public class AnotherAnnotatedClass {

    private AnnotatedClass annotatedClass;
    private int intIsNotAnnotated;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM