2017-08-29 262 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或因爲它是完全一個不存在的類型。 (註釋處理器可能會調用代碼不編譯。)

我不認爲這會導致我的示例之前編寫的方式的問題,但我認爲值得指出的是,這可能發生。