Assume that I have this class:
public class MyClass extends Ancestor{
@MyAnnotation
void doSomething(){
}
@MyAnnotation
void doAnotherthing(String[] args){
}
}
public class Ancestor{
@MyAnnotation
void doFirst(){
}
}
In my annotation processor I have a TypeElement
instance of MyClass
.
How can I find annotated methods with @MyAnnotation
in both MyClass
and its ancestor?
( I know it's possible with RoundEnvironment
but i don't want to use it)
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;
}
Of course, you could also filter for e.g. only methods with e.getKind() == ElementKind.METHOD
.
Elements
is necessary because you want to find the method on the superclass as well. It's possible to do without it, but it's really much more work than necessary.
See Elements#getAllMembers
, Element#getAnnotation
and also TypeElement#getEnclosedElements
.
I know it's possible with RoundEnvironment but i don't want to use it
From the documentation for 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.
So actually, RoundEnvironment
may or may not work for finding annotated elements in general, depending on what you're doing. The methods on RoundEnvironment
are specifically useful for finding the elements which are annotated with the annotation you are processing.
Also of course it's pretty terrible if you want to reduce the search to some smaller scope, in your case, MyClass
. RoundEnvironment
finds everything. If we wanted to, say, find methods that some particular class Bar
overrides from its superclass Foo
, RoundEnvironment
is very awkward for that. We'd have to find all methods that override anything, then use getEnclosingElement()
to find the ones that belong to Bar
.
If, for example, you were writing an annotation processor for MyAnnotation
, then it would make much more sense to use RoundEnvironment
, because annotations are not necessarily processed in a single round. Searching for annotations yourself instead of going through RoundEnvironment
could result in you finding annotations that you've already processed on a prior round.