Reputation: 817
I am using a annotation processor to process annotations of method parameters.
public void multiply(@IntArg int a){
...
}
The annotations types used for the parameters have an annotation, @Argument
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.PARAMETER})
@Argument
public @interface IntArg {
}
Now, when my annotation processor is running, I want to check if a parameter annotation (@IntArg
) has the @Argument
annotation. I do this by executing the following code.
VariableElement param = ... //The parameter
for (AnnotationMirror mirror : param.getAnnotationMirrors()) {
Argument arg = mirror.getAnnotationType().getAnnotation(Argument.class);
if(arg != null) {//Args is always null
...
}
}
For some reason arg
is always null. Is there a reason why the annotation is not returned?
Upvotes: 3
Views: 766
Reputation: 37875
I think what you need is this:
VariableElement param = ...;
for (AnnotationMirror mirror : param.getAnnotationMirrors()) {
DeclaredType t = mirror.getAnnotationType();
// (Filter out ErrorType: see my addendum.)
if (t.getKind() == TypeKind.DECLARED) {
Element e = t.asElement();
// (This should always be true.)
if (e.getKind() == ElementKind.ANNOTATION_TYPE) {
Argument a = e.getAnnotation(Argument.class);
// ...
}
}
}
From DeclaredType
and TypeElement
:
While a
TypeElement
represents a class or interface element, a DeclaredType represents a class or interface type, the latter being a use (or invocation) of the former.
So if you want to examine a declaration somehow, you want the element rather than the type.
Note that I also could have casted e
to a TypeElement
in the above snippet; there was just no particular reason to.
Quick addendum regarding my edit: I think it's probably correct to check the TypeKind
here because it's possible for getAnnotationType()
to return an ErrorType
. This could happen if I did something like this:
void m(@IntArg @TypeWhichDoesntExist int arg0) {
}
Where TypeWhichDoesntExist
is a type which doesn't exist, for example because it's not imported, because it's an @interface
which is generated by another annotation processor or because it's altogether a non-existent type. (Annotation processors may be invoked with code that doesn't compile.)
I don't think this would have caused a problem with the way my example was written before, but I think it's worthwhile to point out that this could happen.
Upvotes: 5