Java編譯時注解(RetentionPolicy.CLASS)(二)——JavaPoet

在使用編譯時注解時,需要在編譯期間對注解進行處理召娜,在這里我們沒辦法影響程序的運行邏輯惊楼,但我們可以進行一些需處理秸讹,比如生成一些功能性代碼來輔助程序的開發(fā)璃诀,最常見的是生成.java 源文件蔑匣,并在程序中可以調(diào)用到生成的文件裁良。這樣我們就可以用注解來幫助我們處理一些固定邏輯的重復(fù)性代碼(如butterknife),提高開發(fā)的效率牧抵。

通過注解處理器來生成 .java 源文件基本上都會使用javapoet 這個庫彼棍,JavaPoet一個是用于產(chǎn)生 .java 源文件的輔助庫座硕,它可以很方便地幫助我們生成需要的.java 源文件涕蜂,下面來看下具體使用方法。

JavaPoet

在使用前需要先引入這個庫蜘拉,和 AutoService一樣可以通過**AndroidStudio **直接添加有鹿,如下:

image

下面以最簡單的 HelloWorld 例子來看下怎么使用JavaPoet葱跋。

先定義一個注解:

/** 
 * JavaPoet HelloWorld 例子 
 */  
@Retention(RetentionPolicy.CLASS)  
@Target(ElementType.TYPE)  
public @interface JPHelloWorld {  
}  

在定義個注解處理器來處理這個注解:

/** 
 * 處理HelloWorld注解. 
 */  
@AutoService(Processor.class)  
public class HelloWorldProcess extends AbstractProcessor {  
  
    private Filer filer;  
  
    @Override  
    public synchronized void init(ProcessingEnvironment processingEnv) {  
        super.init(processingEnv);  
        // Filer是個接口娱俺,支持通過注解處理器創(chuàng)建新文件  
        filer = processingEnv.getFiler();  
    }  
  
    @Override  
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {  
        for (TypeElement element : annotations) {  
            if (element.getQualifiedName().toString().equals(JPHelloWorld.class.getCanonicalName())) {  
                // 創(chuàng)建main方法  
                MethodSpec main = MethodSpec.methodBuilder("main")  
                        .addModifiers(Modifier.PUBLIC, Modifier.STATIC)  
                        .returns(void.class)  
                        .addParameter(String[].class, "args")  
                        .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")  
                        .build();  
                // 創(chuàng)建HelloWorld類  
                TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")  
                        .addModifiers(Modifier.PUBLIC, Modifier.FINAL)  
                        .addMethod(main)  
                        .build();  
  
                try {  
                    // 生成 com.example.HelloWorld.java  
                    JavaFile javaFile = JavaFile.builder("com.example", helloWorld)  
                            .addFileComment(" This codes are generated automatically. Do not modify!")  
                            .build();  
                    // 生成文件  
                    javaFile.writeTo(filer);  
                } catch (IOException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
        return true;  
    }  
  
    @Override  
    public Set<String> getSupportedAnnotationTypes() {  
        Set<String> annotations = new LinkedHashSet<>();  
        annotations.add(JPHelloWorld.class.getCanonicalName());  
        return annotations;  
    }  
  
    @Override  
    public SourceVersion getSupportedSourceVersion() {  
        return SourceVersion.latestSupported();  
    }  
}  

在用 JavaPoet 來生成一個HelloWorld.java文件之前模庐,我們還必須在 init()方法里獲取到 Filer掂碱,這是一個用來輔助創(chuàng)建文件的接口,我們生成文件都通過它來處理疼燥。在 process()方法先創(chuàng)建了個 MethodSpec 表示一個方法,再創(chuàng)建一個 TypeSpec 表示一個類并添加上前面創(chuàng)建的方法搏恤,最后用 JavaFile 來生成對應(yīng)的HelloWorld.java 并寫入文件湃交。

這是最簡單的例子搞莺,整個語法結(jié)構(gòu)也很清晰,相信做編程的看到這些使用方法都能猜到是做什么用的迈喉,我就沒詳細說了温圆。除了這個例子,Github上還有很多其它示例岁歉,如果你想很好地了解編譯時注解的使用的話锅移,還是很有必要把每個例子都過一遍,如果不想自己敲粘貼復(fù)制下很容易的非剃。

在代碼中使用定義的注解:

@JPHelloWorld  

public class MainActivity extends AppCompatActivity{  

    // ...  

}  

重新 Make 下工程就可以看到生成的 **HelloWorld.java **文件了备绽,目錄如下:

image

可以看到已經(jīng)成功生成了 HelloWorld.java 文件疯坤,注意生成文件所在的目錄,現(xiàn)在我們就可以在項目中直接使用這個 java 類了眠冈。當然了蜗顽,這個例子沒有什么實際的使用價值,你可以參考其它例子來生成你想要的代碼雇盖,用法是很多的崔挖。

這里只寫了個最簡單的例子,沒有深入更詳細的使用方法薛匪,等后面有時間再來整理個更詳細的介紹脓鹃。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瘸右,一起剝皮案震驚了整個濱河市太颤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌苗胀,老刑警劉巖瓦堵,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菇用,死亡現(xiàn)場離奇詭異惋鸥,居然都是意外死亡悍缠,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門滤港,熙熙樓的掌柜王于貴愁眉苦臉地迎上來趴拧,“玉大人山叮,你說我怎么就攤上這事屁倔∧弘剩” “怎么了往衷?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵炼绘,是天一觀的道長。 經(jīng)常有香客問我驮捍,道長脚曾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任珊泳,我火速辦了婚禮色查,結(jié)果婚禮上撞芍,老公的妹妹穿的比我還像新娘序无。我一直安慰自己,他們只是感情好晶通,可當我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著哟玷,像睡著了一般狮辽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天隘竭,我揣著相機與錄音塘秦,去河邊找鬼。 笑死动看,一個胖子當著我的面吹牛尊剔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播菱皆,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼仇轻,長吁一口氣:“原來是場噩夢啊……” “哼篷店!你這毒婦竟也來了疲陕?” 一聲冷哼從身側(cè)響起蹄殃,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤讳苦,失蹤者是張志新(化名)和其女友劉穎鸳谜,沒想到半個月后卿堂,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體览绿,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡妻导,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了胰苏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硕并。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖乙濒,靈堂內(nèi)的尸體忽然破棺而出么库,到底是詐尸還是另有隱情廊散,我是刑警寧澤允睹,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站米者,受9級特大地震影響蔓搞,放射性物質(zhì)發(fā)生泄漏喂分。R本人自食惡果不足惜机蔗,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一梆掸、第九天 我趴在偏房一處隱蔽的房頂上張望酸钦。 院中可真熱鬧汇恤,春花似錦因谎、人聲如沸财岔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酿雪。三九已至指黎,卻和暖如春醋安,著一層夾襖步出監(jiān)牢的瞬間吓揪,已是汗流浹背磺芭。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留放棒,地道東北人间螟。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像摩泪,于是被迫代替她去往敵國和親见坑。 傳聞我的和親對象是個殘疾皇子荞驴,可洞房花燭夜當晚...
    茶點故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內(nèi)容