2017-08-29 172 views
0

我正在使用注释处理器来处理方法参数的注释。Java注释处理器,带注释的注释类型

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

那么,你的参数没有'@ Argument'注释,所以'arg'总是'null' ... –

+0

我没有得到参数的'@ Argument'注解,我得到注解在这种情况下,AnnotationType是IntArg。 – Joba

回答

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); 
      // ... 
     } 
    } 
} 

DeclaredTypeTypeElement

虽然TypeElement代表一个类或接口元素,一个的declaredType代表的类或接口类型为,后者是前者的用途(或调用)。

所以,如果你想以某种方式检查一个声明,你想要的是元素而不是类型。

请注意,我也可以在上面的代码片段中将e铸造成TypeElement;没有特别的理由。


关于我的编辑编快:我认为这可能是正确的在这里检查TypeKind,因为它可能为getAnnotationType()返回一个ErrorType。这可能发生,如果我做了这样的事情:

void m(@IntArg @TypeWhichDoesntExist int arg0) { 
} 

哪里是因为它不是进口不存在的,例如一个类型,因为它是由另一注释处理器生成的@interface或因为它是完全一个不存在的类型。 (注释处理器可能会调用代码不编译。)

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