2016-04-22 60 views
0

假設我有這個類:如何在TypeElement中找到註釋的方法?

public class MyClass extends Ancestor{ 

    @MyAnnotation 
    void doSomething(){ 
    } 

    @MyAnnotation 
    void doAnotherthing(String[] args){ 
    } 

} 

public class Ancestor{ 

    @MyAnnotation 
    void doFirst(){ 
    } 
} 

在我的註釋處理器我有一個MyClass實例TypeElement

如何在MyClass及其祖先中找到帶有@MyAnnotation的註釋方法?

(我知道這是可能的,但RoundEnvironment我不想使用它)

回答

4
static Set<Element> getAnnotatedElements(
    Elements elements, 
    TypeElement type, 
    Class<? extends Annotation> annotation) 
{ 
    Set<Element> found = new HashSet<Element>(); 
    for (Element e : elements.getAllMembers(type)) { 
     if (e.getAnnotation(annotation) != null) 
      found.add(e); 
    } 
    return found; 
} 

當然,你也可以篩選例如只有方法e.getKind() == ElementKind.METHOD

Elements是必要的,因爲你也想在超類上找到方法。沒有它是可能的,但它確實比沒有必要的工作多得多。

參見Elements#getAllMembers,Element#getAnnotation還有TypeElement#getEnclosedElements

我知道這是可能的RoundEnvironment但我不希望使用它

從文檔RoundEnvironment#getElementsAnnotatedWith

這隻包的元素和類型元素包括在這一輪註釋處理或者聲明在其中的成員,構造函數,參數或類型參數的聲明。

因此,實際上,RoundEnvironment可能或可能不適用於查找標註的元素,具體取決於您在做什麼。 RoundEnvironment上的方法是,具體來說對找到用您正在處理的註釋進行註釋的元素很有用。

當然,如果您想將搜索範圍縮小到一些較小的範圍,那麼這很糟糕,在您的情況下,MyClassRoundEnvironment發現應有盡有。如果我們想要找到一些特定的類別覆蓋超類Foo的方法,那麼RoundEnvironment就非常尷尬。我們必須找到全部方法覆蓋任何內容,然後使用getEnclosingElement()找到屬於Bar的方法。

如果,例如,你在寫註釋處理器MyAnnotation,那麼它將使使用RoundEnvironment更有意義,因爲註解不一定在單輪處理。自己搜索註釋而不是通過RoundEnvironment可能會導致您找到已在前一輪處理過的註釋。

0

如果你寫,你必須使用RoundEnvironment註解處理器。這就是註釋處理器的工作方式。請記住,javac的可能根據它跑你幾次內部需求

相關問題