注释处理未知注释

时间:2016-12-08 13:45:06

标签: java annotations java-8 preprocessor

目前我正在编写一个Annotation处理器,它将生成新的源代码。这个处理器与应用程序本身是隔离的,因为它是构建项目的一个步骤,我从应用程序中分离了整个构建系统。

这是问题的开始,因为我想处理在应用程序中创建的Annotation。我们将其命名为 CustomAnnotation 。使用完全限定名称 com.company.api.annotation.CustomAnnotation

在处理器中,我可以通过完全限定的名称搜索注释,这真的很棒。现在我似乎能够获得注释的方法,字段等,因为我可以使用 TypeElement 而不是 Class 来调用函数 getElementsAnnotatedWith

现在我们的CustomAnnotation中包含字段和变量,通常我会像这样得到Annotation:Class annotation = Element.getAnnotation(Class)但我不能使用它,因为CustomAnnotation不能用作Class Object。(当然,它& #39;处理器不知道)我尝试使用TypeMirror和其他可用的东西,但似乎没有任何工作。

有人知道让Annotation读取它的价值的方法吗?

编辑: 让我们来看看这个实现:

@SupportedAnnotationTypes( "com.company.api.annotation.CustomAnnotation" )
@SupportedSourceVersion( SourceVersion.RELEASE_8 )  
public class CustomProcessor extends AbstractProcessor
{

  public CustomProcessor()
  {
    super();
  }

  @Override
  public boolean process( Set<? extends TypeElement> annotations, RoundEnvironment roundEnv )
  {
    TypeElement test = annotations.iterator().next();

    for ( Element elem : roundEnv.getElementsAnnotatedWith( test ) )
    {
      //Here is where I would get the Annotation element itself to 
      //read the content of it if I can use the Annotation as Class Object. 
      SupportedAnnotationTypes generated = elem.getAnnotation( SupportedAnnotationTypes.class );
    }
 }

但是我不必使用 CustomAnnotation.class ,因为它不存在于此环境中。如何在不拥有Class对象的情况下执行此操作?

1 个答案:

答案 0 :(得分:3)

您可以将注释查询为AnnotationMirror,不需要注释类型为加载的运行时Class

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    for(TypeElement test: annotations) {
        for( Element elem : roundEnv.getElementsAnnotatedWith( test ) ) {
            System.out.println(elem);
            for(AnnotationMirror am: elem.getAnnotationMirrors()) {
                if(am.getAnnotationType().asElement()==test)
                    am.getElementValues().forEach((ee,av) ->
                        System.out.println("\t"+ee.getSimpleName()+" = "+av.getValue())
                    );
            }
        }
    }
    return true;
}