如何在TypeElement中查找带注释的方法?

时间:2016-04-22 19:34:05

标签: java annotation-processing

假设我有这门课程:

public class MyClass extends Ancestor{

    @MyAnnotation
    void doSomething(){
    }

    @MyAnnotation
    void doAnotherthing(String[] args){
    }

}

public class Ancestor{

    @MyAnnotation
    void doFirst(){
    }
}

在我的注释处理器中,我有一个TypeElement MyClass实例。

如何在@MyAnnotation及其祖先中找到带MyClass的注释方法?

(我知道这可能与RoundEnvironment有关,但我不想使用它)

2 个答案:

答案 0 :(得分:4)

static Set<Element> getAnnotatedElements(
    Elements elements,
    TypeElement type,
    Class<? extends Annotation> annotation)
{
    Set<Element> found = new HashSet<Element>();
    for (Element e : elements.getAllMembers(type)) {
        if (e.getAnnotation(annotation) != null)
            found.add(e);
    }
    return found;
}

当然,你也可以过滤只有e.getKind() == ElementKind.METHOD的方法。

Elements是必要的,因为你也希望在超类上找到方法。没有它可以做到这一点,但实际上工作要多得多。

请参阅Elements#getAllMembersElement#getAnnotation以及TypeElement#getEnclosedElements

  

我知道RoundEnvironment有可能但我不想使用它

来自RoundEnvironment#getElementsAnnotatedWith的文档:

  

仅返回此一轮注释处理中的包元素和类型元素 ,或者返回在其中声明的成员,构造函数,参数或类型参数的声明。

实际上,RoundEnvironment可能会或可能不会用于查找带注释的元素,具体取决于您正在做什么。 RoundEnvironment上的方法具体可用于查找使用您正在处理的注释进行注释的元素。

当然,如果您希望将搜索范围缩小到较小的范围(在您的情况下为MyClass),那将非常糟糕。 RoundEnvironment找到所有内容。如果我们想要查找某些特定类Bar覆盖其超类Foo的方法,RoundEnvironment对此非常尴尬。我们必须找到覆盖任何内容的所有方法,然后使用getEnclosingElement()查找属于Bar的方法。

例如,如果您正在为MyAnnotation 编写注释处理器,那么使用RoundEnvironment会更有意义,因为注释不一定在一轮。自己搜索注释而不是通过RoundEnvironment可能会导致您找到已在前一轮处理过的注释。

答案 1 :(得分:0)

如果您编写注释处理器,则必须使用RoundEnvironment。这就是注释处理器的工作方式。请记住,javac可能会根据其内部需求多次运行您