假设我有这门课程:
public class MyClass extends Ancestor{
@MyAnnotation
void doSomething(){
}
@MyAnnotation
void doAnotherthing(String[] args){
}
}
public class Ancestor{
@MyAnnotation
void doFirst(){
}
}
在我的注释处理器中,我有一个TypeElement
MyClass
实例。
如何在@MyAnnotation
及其祖先中找到带MyClass
的注释方法?
(我知道这可能与RoundEnvironment
有关,但我不想使用它)
答案 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#getAllMembers
,Element#getAnnotation
以及TypeElement#getEnclosedElements
。
我知道RoundEnvironment有可能但我不想使用它
来自RoundEnvironment#getElementsAnnotatedWith
的文档:
仅返回此一轮注释处理中的包元素和类型元素 ,或者返回在其中声明的成员,构造函数,参数或类型参数的声明。
实际上,RoundEnvironment
可能会或可能不会用于查找带注释的元素,具体取决于您正在做什么。 RoundEnvironment
上的方法具体可用于查找使用您正在处理的注释进行注释的元素。
当然,如果您希望将搜索范围缩小到较小的范围(在您的情况下为MyClass
),那将非常糟糕。 RoundEnvironment
找到所有内容。如果我们想要查找某些特定类Bar
覆盖其超类Foo
的方法,RoundEnvironment
对此非常尴尬。我们必须找到覆盖任何内容的所有方法,然后使用getEnclosingElement()
查找属于Bar
的方法。
例如,如果您正在为MyAnnotation
编写注释处理器,那么使用RoundEnvironment
会更有意义,因为注释不一定在一轮。自己搜索注释而不是通过RoundEnvironment
可能会导致您找到已在前一轮处理过的注释。
答案 1 :(得分:0)
如果您编写注释处理器,则必须使用RoundEnvironment。这就是注释处理器的工作方式。请记住,javac可能会根据其内部需求多次运行您