Java注释处理器,带注释的注释类型

Java注释处理器,带注释的注释类型,java,compilation,annotations,Java,Compilation,Annotations,我使用注释处理器来处理方法参数的注释 public void multiply(@IntArg int a){ ... } 用于参数的注释类型有一个注释@Argument @Retention(RetentionPolicy.CLASS) @Target({ElementType.PARAMETER}) @Argument public @interface IntArg { } 现在,当注释处理器运行时,我想检查参数注释(@IntArg)是否有@参数注释。我通过执行以下代码来实现这

我使用注释处理器来处理方法参数的注释

public void multiply(@IntArg int a){
    ...
}
用于参数的注释类型有一个注释@Argument

@Retention(RetentionPolicy.CLASS)
@Target({ElementType.PARAMETER})
@Argument
public @interface IntArg {
}
现在,当注释处理器运行时,我想检查参数注释(
@IntArg
)是否有
@参数
注释。我通过执行以下代码来实现这一点

VariableElement param = ... //The parameter
for (AnnotationMirror mirror : param.getAnnotationMirrors()) {
    Argument arg = mirror.getAnnotationType().getAnnotation(Argument.class);
    if(arg != null) {//Args is always null
        ...
    }
}

由于某种原因,
arg
始终为空。注释没有返回有什么原因吗?

我想您需要的是:

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
;只是没有特别的理由


关于我的编辑的快速补充:我认为在这里检查可能是正确的,因为
getAnnotationType()
可以返回一个。如果我这样做的话,可能会发生这种情况:

void m(@IntArg @TypeWhichDoesntExist int arg0) {
}
其中,
typewhichDoesnTexsist
是不存在的类型,例如,因为它没有导入,因为它是由另一个注释处理器生成的
@接口,或者因为它完全不存在。(注释处理器可以使用未编译的代码调用。)


我不认为这会对我以前编写示例的方式造成问题,但我认为值得指出的是,这可能会发生。

我认为您需要的是:

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
;只是没有特别的理由


关于我的编辑的快速补充:我认为在这里检查可能是正确的,因为
getAnnotationType()
可以返回一个。如果我这样做的话,可能会发生这种情况:

void m(@IntArg @TypeWhichDoesntExist int arg0) {
}
其中,
typewhichDoesnTexsist
是不存在的类型,例如,因为它没有导入,因为它是由另一个注释处理器生成的
@接口,或者因为它完全不存在。(注释处理器可以使用未编译的代码调用。)


我不认为这会导致我以前编写示例的方式出现问题,但我认为值得指出的是,这可能会发生。

好吧,您的参数没有
@参数
注释,因此,
arg
将始终为
null
…我没有得到参数的
@参数
注释,我得到的是AnnotationType的注释,在本例中为IntArg。好吧,您的参数没有
@参数
注释,因此,
arg
将始终为
null
…我没有得到参数的
@参数
注释,我得到的是AnnotationType的注释,在本例中为IntArg。