APT如何处理嵌套注解类的注解

8

我正在尝试使用Java编写注解处理器。该注解处理器需要识别以下示例中的已注释嵌套类。我将首先处理已注释类,然后处理其内部注释。这是在编译时执行的,并且我没有有关正在处理的类的现有知识。Foo可能有多个嵌套类。如何处理所有这些嵌套类的注释。

@MyAnnotation(value="Something important")
public class Foo
{
    private Integer A;

    @MyMethodAnnotation(value="Something Else")
    public Integer getA() { return this.A; }

    @MyAnnotation(value="Something really important")
    private class Bar
    {
        private Integer B;

        @MyMethodAnnotation(value="Something Else that is very Important")
        public Integer getB() { return this.B }     
    }
}

在处理过程中,我该如何访问嵌套的Bar类、它的注解'MyAnnotation'和它的'MyMethodAnnotation'? 以下代码仅打印有关类Foo的信息。如何处理有关Bar的信息?

for (Element element : env.getElementsAnnotatedWith(MyAnnotation.class)) {
    if ( element.getKind().equals(ElementKind.CLASS) )
    {
        System.out.println(element.getKind().name() + " " + element.getSimpleName() );
        processInnerClassElement(element);
    }
    else
    {
        System.out.println(element.getKind().name() + " " + element.getSimpleName() );
    }    
}

...


private void processInnerClassElement(Element element)
{
    for (Element e : element.getEnclosedElements() )
    {
        if ( e.getKind().equals(ElementKind.CLASS) )
        {
            System.out.println(e.getKind().name() + " " + e.getSimpleName() );
            processInnerClassElement(e);
        }
        else
        {
            System.out.println(e.getKind().name() + " " + e.getSimpleName()  );
        }
    }
}

我尝试使用以下代码访问嵌套类Bar中的元素:for ( Element e : env.getElementsAnnotatedWith(EmfInfo.class) ) {但是这只返回最外层的类Foo。 - sholmes
2个回答

1

我想这取决于这些注释之间的关系。

您可以在@SupportedAnnotationTypes中声明所有注释,并在process-method中有几个块,例如:

for (Element element : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {
    MyAnnotation myAnnotation = element.getAnnotation(MyAnnotation.class);
    if (myAnnotation != null) {
        doSomething(myAnnotation, element);
    }
}

for (Element element : roundEnv.getElementsAnnotatedWith(MyMethodAnnotation.class)) {
    MyMethodAnnotation myMethodAnnotation = element.getAnnotation(MyMethodAnnotation.class);
    if (myMethodAnnotation != null) {
        doSomething(myMethodAnnotation, element);
    }
}

否则,您可以使用element.getEnclosedElements()element.getEnclosingElement()来实现您想要的功能。

这个完美地运作了。实际上,我的源代码存在问题导致了错误。在纠正了这个问题之后,上述解决方案可以处理嵌套类的注释。 - sholmes

-1
你需要从ClassMethod中获取一些方法来完成这个任务,具体来说是获取在Foo中声明的类、这些类上的注解、在这些类中声明的方法以及这些方法上的注解。以下是一个快速示例:
public static void main(String... args) {
    for (Class<?> declaredClass : Foo.class.getDeclaredClasses()) {
        MyAnnotation myAnnotation = declaredClass.getAnnotation(MyAnnotation.class);
        // Process value of class annotation here
        for (Method method : declaredClass.getDeclaredMethods()) {
            MyMethodAnnotation myMethodAnnotation = method.getAnnotation(MyMethodAnnotation.class);
            // Process value of method annotation here
        }
    }
}

阅读有关Java反射的文档可能会很有启发性:http://docs.oracle.com/javase/tutorial/reflect/index.html


3
您在谈论反射API,但OP提到的是注解处理器,它不是反射。注解处理器是Java编译器的扩展API之一。 - AlexR
我正在使用Java6中编译器的扩展——注解处理工具。在使用注解处理工具进行编译时,我不知道嵌套类的名称。 - sholmes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接