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

How to find annotated methods in TypeElement?

假设我有这个 class:

public class MyClass extends Ancestor{

    @MyAnnotation
    void doSomething(){
    }

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

}

public class Ancestor{

    @MyAnnotation
    void doFirst(){
    }
}

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

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

(我知道 RoundEnvironment 可以,但我不想使用它)

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

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 是必需的,因为您也想在 superclass 上找到该方法。没有它也可以,但它确实比必要的工作多得多。

参见 Elements#getAllMembers, Element#getAnnotation and also TypeElement#getEnclosedElements

I know it's possible with RoundEnvironment but i don't want to use it

来自 RoundEnvironment#getElementsAnnotatedWith 的文档:

Only package elements and type elements included in this round of annotation processing, or declarations of members, constructors, parameters, or type parameters declared within those, are returned.

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

当然,如果您想将搜索缩小到某个更小的范围,在您的情况下,MyClass,这当然是非常糟糕的。 RoundEnvironment 找到 一切 。如果我们想,比如说,找到一些特定的 class Bar 从它的 superclass Foo 覆盖的方法,RoundEnvironment 就非常尴尬。我们必须找到覆盖任何东西的 all 方法,然后使用 getEnclosingElement() 找到属于 Bar.

的方法

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