我正在使用注释处理器来处理方法参数的注释。
public void multiply(@IntArg int a){
...
}
用于参数的注释类型具有注释@Argument
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.PARAMETER})
@Argument
public @interface IntArg {
}
现在,当我的注释处理器运行时,我想检查参数注释(@IntArg
)是否具有@Argument
注释。我是通过执行以下代码来完成的。
VariableElement param = ... //The parameter
for (AnnotationMirror mirror : param.getAnnotationMirrors()) {
Argument arg = mirror.getAnnotationType().getAnnotation(Argument.class);
if(arg != null) {//Args is always null
...
}
}
由于某种原因,arg
始终为空。是否有理由不返回注释?
答案 0 :(得分:2)
我认为你需要的是:
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);
// ...
}
}
}
虽然
TypeElement
表示类或接口元素,但DeclaredType表示类或接口类型,后者是一个用途(或前者的调用。
因此,如果您想以某种方式检查声明,则需要元素而不是类型。
请注意,我也可以将e
投放到上述代码段中的TypeElement
;没有特别的理由。
关于我的修改的快速附录:我认为在此处查看TypeKind
可能是正确的,因为getAnnotationType()
可能会返回ErrorType
。如果我做了这样的事情,就会发生这种情况:
void m(@IntArg @TypeWhichDoesntExist int arg0) {
}
其中TypeWhichDoesntExist
是一种不存在的类型,例如因为它未导入,因为它是@interface
由另一个注释处理器生成的或者因为它完全是一种不存在的类型。 (可以使用不编译的代码调用注释处理器。)
我不认为这会导致我之前编写示例的方式出现问题,但我认为值得注意的是,这可能会发生。