質問

I am trying to write an annotation processor using java. This annotation processor needs to identify annotated nested classes within an annotated class as seen below. I will process the annotated classes first then process their inner annotations. This is performed at compile time and I will have no existing knowledge of the class being processed. It is possible to have multiple nested classes within Foo. How do I process the annotations of all these nested classes.

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

How can I get access to the nested Bar class, it's annotation 'MyAnnotation' and its 'MyMethodAnnotation' during processing? The following code only prints out information about class Foo. How can I process information about 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()  );
        }
    }
}
役に立ちましたか?

解決

I guess it depends how these annotation relate to each other.

You could simply declare all the annotations in @SupportedAnnotationTypes and have several blocks in the process-method like:

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);
    }
}

Otherwise you might be able to use element.getEnclosedElements() and element.getEnclosingElement() to achieve what you want.

他のヒント

You'll need a few methods from Class and Method to do this, specifically to get the classes declared in Foo, the annotations on those classes, the methods declared in those classes, and the annotations on those methods. Here is a quick example:

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

It might be insightful to read through the documentation about reflection in Java: http://docs.oracle.com/javase/tutorial/reflect/index.html

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top