Java注解處理器使用注意事項(xiàng)

Java注解處理器使用注意事項(xiàng)

目錄

[TOC]

注解

元注解

@Target

用于標(biāo)記可以應(yīng)用于哪些類(lèi)型上.

類(lèi)型說(shuō)明

元素類(lèi)型 適用場(chǎng)合
ANOTATION_TYPE 注解類(lèi)型聲明
PACKAGE
TYPE 類(lèi),枚舉,接口,注解
METHOD 方法
CONSTRUCTOR 構(gòu)造方法
FIELD 成員域,枚舉常量
PARAMETER 方法或構(gòu)造器參數(shù)
LOCAL_VARIABLE 局部變量
TYPE_PARAMETER 類(lèi)型參數(shù)
TYPE_USE 類(lèi)型用法

@Retention

用于標(biāo)注注解保留時(shí)間

類(lèi)型說(shuō)明

保留類(lèi)型 說(shuō)明
SOURCE 只保留到源碼中,編譯出來(lái)的class不存在
CLASS 保留到class文件中,但是JVM不會(huì)加載
RUNTIME 一直存在,JVM會(huì)加載,可用反射獲取

注解處理器

方法重載注意事項(xiàng)

  • 為兼容JDK_6,最好重載方法getSupportedAnnotationTypesgetSupportedSourceVersion而不是使用注釋@SupportedAnnotationTypes@SupportedSourceVersion

注解處理器的注冊(cè)

方式一

res/META-INF/services/javax.annotation.processing.Processor添加注解處理器的類(lèi)全路徑及名稱(chēng),如果有多個(gè)注解處理器,換行分割.

舉例:

com.yxf.socketframe.annotation.ClientCallbackProcessor
com.yxf.socketframe.annotation.ServerInterfaceProcessor

有一個(gè)非常巨大的坑,如果是在Android Studio中做這些事情,需要在庫(kù)的build.gradle中添加如下配置

sourceSets {
    main {
        java {
            srcDir 'src'
        }
        resources {
            srcDir 'res'
        }
    }
}

不然注解處理器不生效.

方式二

添加對(duì)谷歌自動(dòng)注冊(cè)注解庫(kù)的引用

implementation ‘com.google.auto.service:auto-service:1.0-rc4’ 

在注解處理器類(lèi)前面聲明

@AutoService(Processor.class)

配置

在項(xiàng)目app的build.gradle中添加

android {
    defaultConfig {
        javaCompileOptions {
            annotationProcessorOptions {
                includeCompileClasspath true
            }
        }
    }
}   

或者使用annotationProcessor來(lái)編譯有注解處理器的部分.

常用實(shí)現(xiàn)

getSupportedSourceVersion

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

getSupportedAnnotationTypes

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> annotations = new LinkedHashSet<String>();
        annotations.add(ServerInterface.class.getCanonicalName());
        return annotations;
    }

process

從EventBus源碼中借鑒

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {

        round++;
        messager.printMessage(Diagnostic.Kind.NOTE, "Processing round " + round + ", new annotations: " +
                !set.isEmpty() + ", processingOver: " + roundEnvironment.processingOver());

        if (roundEnvironment.processingOver()) {
            if (!set.isEmpty()) {
                messager.printMessage(Diagnostic.Kind.ERROR,
                        "Unexpected processing state: annotations still available after processing over");
                return false;
            }
        }

        if (set.isEmpty()) {
            return false;
        }

        if (writerRoundDone) {
            messager.printMessage(Diagnostic.Kind.ERROR,
                    "Unexpected processing state: annotations still available after writing.");
        }

        if (!generateSourceFile(set, roundEnvironment)) {
            return false;
        }

        writerRoundDone = true;
        return true;
    }

Element

類(lèi)型說(shuō)明

Element 說(shuō)明
TypeElement 一般是類(lèi)或者接口元素
ExecutableElement 類(lèi)方法或者接口方法元素
VariableElement 成員變量,參數(shù)元素

屬性獲取

屬性的獲取感覺(jué)有點(diǎn)讓人心累,無(wú)法直接獲得所屬對(duì)象的class.

一般通過(guò)Element.getQualifiedName(),Element.getSimpleName()這兩個(gè)方法獲得類(lèi)名和路徑.

通過(guò)Element.getKind()獲得元素類(lèi)型.

通過(guò)ExecutableElement.getReturnType().getKind()獲得方法返回類(lèi)型.

通過(guò)VariableElement.asType().toString()獲得參數(shù)類(lèi)型,或者通過(guò)VariableElement.asType().getKind()獲取,但是這種方式只能獲得基礎(chǔ)類(lèi)型的類(lèi)型.

通過(guò)Element.getEnclosedElements()獲得子元素,通過(guò)Element.getEnclosingElement()獲得父元素.

注意

  • 應(yīng)當(dāng)注意的是,在生成Java源文件的代碼中,生產(chǎn)的內(nèi)部變量盡可能添加下劃線(xiàn),以避免和動(dòng)態(tài)參數(shù)產(chǎn)生變量名沖突

  • 注解處理器和庫(kù)之間應(yīng)當(dāng)分離作為兩個(gè)庫(kù)

  • 如果自建Java庫(kù),注解處理器和注解分離,則在這個(gè)庫(kù)中使用的注解,注解處理器將不會(huì)執(zhí)行,所以不要在自己的庫(kù)中使用自己的注解.

  • process方法返回false會(huì)停止編譯,如果編譯出現(xiàn)問(wèn)題,可以通過(guò)Messager打印錯(cuò)誤信息,并且process返回false.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末披坏,一起剝皮案震驚了整個(gè)濱河市裸准,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蜒滩,老刑警劉巖滨达,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異俯艰,居然都是意外死亡捡遍,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)竹握,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)画株,“玉大人,你說(shuō)我怎么就攤上這事啦辐∥酱” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵芹关,是天一觀的道長(zhǎng)续挟。 經(jīng)常有香客問(wèn)我,道長(zhǎng)侥衬,這世上最難降的妖魔是什么诗祸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮浇冰,結(jié)果婚禮上贬媒,老公的妹妹穿的比我還像新娘。我一直安慰自己肘习,他們只是感情好际乘,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著漂佩,像睡著了一般脖含。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上投蝉,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天养葵,我揣著相機(jī)與錄音,去河邊找鬼瘩缆。 笑死关拒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的庸娱。 我是一名探鬼主播着绊,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼熟尉!你這毒婦竟也來(lái)了归露?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤斤儿,失蹤者是張志新(化名)和其女友劉穎剧包,沒(méi)想到半個(gè)月后恐锦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疆液,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年一铅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枚粘。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡馅闽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出馍迄,到底是詐尸還是另有隱情福也,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布攀圈,位于F島的核電站暴凑,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赘来。R本人自食惡果不足惜现喳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望犬辰。 院中可真熱鬧嗦篱,春花似錦、人聲如沸幌缝。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)涵卵。三九已至浴栽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間轿偎,已是汗流浹背典鸡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留坏晦,地道東北人萝玷。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像昆婿,于是被迫代替她去往敵國(guó)和親间护。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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

  • Java 中的注解(Annotation) 是一個(gè)很方便的特性在Spring當(dāng)中得到了大量的應(yīng)用 , 我們也可以開(kāi)...
    _秋天閱讀 8,779評(píng)論 3 22
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架挖诸,建立于...
    Hsinwong閱讀 22,313評(píng)論 1 92
  • 上一篇我們講解了ButterKnife的設(shè)計(jì)思想,理解了ButterKnife綁定相關(guān)源碼的實(shí)現(xiàn)邏輯法精。但是它是怎么...
    Ihesong閱讀 994評(píng)論 0 2
  • 什么是注解注解分類(lèi)注解作用分類(lèi) 元注解 Java內(nèi)置注解 自定義注解自定義注解實(shí)現(xiàn)及使用編譯時(shí)注解注解處理器注解處...
    Mr槑閱讀 1,070評(píng)論 0 3
  • 一路走了數(shù)十載,交流越來(lái)越少狼荞! 總是盯著日常生活開(kāi)支辽装,其實(shí)開(kāi)支從來(lái)不曾少,只是緊點(diǎn)而已 其實(shí)想想有錢(qián)無(wú)錢(qián)都可以慢慢...
    tedychen閱讀 384評(píng)論 0 0