2011-12-05 43 views
4

我想實現基於現有「原型」類生成新類的註釋處理器。Java靜態元編程

import java.util.List 

@MyAnnotation 
class MySuperClassPrototype { 
    static MySuperClassPrototype createInstance() { 
     return new MySuperClassPrototype(); 
    } 
} 

由於下面的代碼。下面的新的源文件(編譯單元)將產生:

import java.util.List 

class MySuperClass { 
    static MySuperClass createInstance() { 
     return new MySuperClass(); 
    } 
    public void specialAddedMethod() { 
     /*...*/ 
    } 
} 

我想複製所有頂級import語句和靜態成員和原型類的不是靜態成員。我使用Compiler Tree API(com.sun.source.tree)進行了很多改進。我可以打印出Tree數據類型,同時替換舊的類名。但有些問題似乎很難。

如果我在樹中得到Tree.Kind.IDENTIFIER,我怎麼才能找到它引用的實際類。我需要用MySuperClass標識符替換所有出現的MySuperClassPrototype標識符,並打印出整棵樹。

可行嗎?

同樣,我需要過濾出@MyAnnotation註釋,並再次用Tree.Kind.IDENTIFIER或Tree.Kind.MEMBER_SELECT表示它。

如何找到由此標識符引用的實際註釋類?

另一個問題是打印出樹。如果我使用toString方法,我得到了不錯的結果,但構造函數打印爲具有「<init>」名稱的方法,而不是與它的類具有相同名稱的方法,因此我需要手動打印每種樹節點。

你可以看到code I've come with here

回答

4

是的,這是可能的,我知道至少有2種方式。首先,「傳統」方式是編寫ant任務/ maven插件/只是命令行Java實用程序,它掃描給定的文件路徑並調用每個類,如Class.forName(className).getAnnotations(MyAnnotation.class)。如果這不是null,則使用反射發現類並執行所需的操作。

其他方法有點困難,但更強大。 你可以實現自己的Processor(實現javax.annotation.processing.Processor甚至更​​好的擴展javax.annotation.processing.AbstractProcessor。 你的處理器將不得不放置到compiler classpath中,當編譯運行,你也可以配置你的IDE(如Eclipse的),它會自動運行運行你的處理器,這是Java編譯器的一種擴展,所以每次eclipse建立你的項目時,它都會運行處理器,並根據你添加的新註釋創建所有新類。

請看看這個project作爲參考