從Annotation到APT(一)

Java注解又稱Java標(biāo)注国葬,是Java語(yǔ)言5.0版本開(kāi)始支持加入源代碼的特殊語(yǔ)法元數(shù)據(jù)
Java語(yǔ)言中的類安吁、方法趋翻、變量睛琳、參數(shù)和包等都可以被標(biāo)注。和Javadoc不同踏烙,Java標(biāo)注可以通過(guò)反射獲取標(biāo)注內(nèi)容师骗。在編譯器生成類文件時(shí),標(biāo)注可以被嵌入到字節(jié)碼中讨惩。Java虛擬機(jī)可以保留標(biāo)注內(nèi)容辟癌,在運(yùn)行時(shí)可以獲取到標(biāo)注內(nèi)容。 當(dāng)然它也支持自定義Java標(biāo)注.

元注解

Java中共有四種元注解:

//表示帶有該注解的元素能被文檔化
@Documented
//表示可被該注解修飾的元素種類
@Target
//表示該注解的作用域
@Retention
//表示該注解被自動(dòng)繼承
@Inherited

Documented

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}```

@Documented表示被該注解修飾的元素能被Javadoc等工具文檔化荐捻,但是注意到被@Target注解修飾且Target只能是Annotation類型黍少,說(shuō)明該注解只能用來(lái)修飾注解。作用域可至運(yùn)行時(shí)处面。

@interface 定義注解的關(guān)鍵字厂置。

#### Target

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}```

注意到Target和Documented注解有所不同,Target注解有方法體魂角,返回值是一個(gè)ElementType類型的數(shù)組昵济,ElementType是一個(gè)枚舉類型,有TYPE(類、接口访忿、枚舉)瞧栗,METHOD(方法),F(xiàn)IELD(字段)海铆,PARAMETER(參數(shù))迹恐,CONSTRUCTOR(構(gòu)造函數(shù)),LOCAL_VARIABLE(局部變量)卧斟,ANNOTATION_TYPE(注解類型)殴边,PACKAGE(包),TYPE_PARAMETER(類型參數(shù)唆涝,1.8)找都,TYPE_USE(類型使用,1.8)廊酣,分別代表可被修飾的元素類型 能耻。Target可傳入一個(gè)或多個(gè)屬性。

@Target(ElementType.ANNOTATION_TYPE)表示Target注解只能用來(lái)修飾注解亡驰,同時(shí)作用域?yàn)檫\(yùn)行時(shí)晓猛。

@Retention

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}```

方法體中RetentionPolicy同樣是一個(gè)枚舉類型,SOURCE(保留在源文件凡辱,編譯時(shí)被丟棄)戒职,CLASS(保留在源文件、編譯后的class字節(jié)碼透乾,在運(yùn)行時(shí)被丟棄)洪燥,RUNTIME(一直保留直到運(yùn)行時(shí))。保留在運(yùn)行時(shí)的可以通過(guò)反射去獲得乳乌。

Retention也只能用來(lái)修飾注解捧韵,且作用域到運(yùn)行時(shí)。

#### Inherited

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}```

Inherited表示注解是被自動(dòng)繼承的汉操,即如果要在當(dāng)前類查找這個(gè)元注解類型再来,但當(dāng)前類并沒(méi)有聲明,將自動(dòng)去其父類去尋找磷瘤,直到找到或者找到頂層父類為止芒篷。注意這個(gè)被這個(gè)元注解標(biāo)注的注解作用在類級(jí)別上,子類可以繼承父類的注解采缚,反之不可以针炉。

Java中常用注解

@Override

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}```

告訴編輯器要復(fù)寫超類的方法。@Override只能用于修飾方法仰担,且作用域只停留在源碼級(jí)別糊识,即編譯時(shí)會(huì)被丟棄绩社,起標(biāo)記作用摔蓝。

#### @SuppressWarnings

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {

String[] value();

}```

用于告訴編輯器忽略警告信息赂苗。可用于修飾類贮尉、接口拌滋、字段、方法猜谚、參數(shù)败砂、構(gòu)造函數(shù)、局部變量魏铅。作用域停留在源碼級(jí)別昌犹。

@SuppressWarnings使用時(shí)需要一個(gè)String類型的數(shù)組,如uncheck(忽略泛型未轉(zhuǎn)換的警告)览芳,deprecation(忽略使用了過(guò)時(shí)的方法或字段警告)等斜姥。

@Deprecated

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}```

用來(lái)告訴編輯器,此方法沧竟、字段等不贊成使用铸敏。作用域?yàn)檫\(yùn)行時(shí)。

# 反射獲得運(yùn)行時(shí)注解

注解由@Retention(RetentionPolicy.RUNTIME)修飾的為運(yùn)行時(shí)注解悟泵,我們可以通過(guò)運(yùn)行時(shí)反射獲得注解信息杈笔。

比如我們自定義一個(gè)注解:

@Inherited
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
String value() default "Boss";
}```

定義注解要用@interface關(guān)鍵字,target為方法糕非,作用域?yàn)檫\(yùn)行時(shí)蒙具,需要傳入一個(gè)String類型的參數(shù),注意到default “Boss”朽肥,即如果沒(méi)有傳參數(shù)將返回“Boss”禁筏,這個(gè)注解的意義為可以在方法體上使用該注解用于告知該函數(shù)的作者。

我們可以這樣用:

    @Author("Jack")
    public void autorTest(){
        System.out.print("I am author");
    }```

如何通過(guò)反射在運(yùn)行時(shí)獲得Author信息呢鞠呈?

public class Main {

public static void main(String[] args) throws ClassNotFoundException {
    String className = "AnnotationTest";
    Method[] methods = Main.class.getClassLoader().loadClass(className).getMethods();

    for (Method method : methods) {
        //判斷該元素是否存在指定注解
        if (method.isAnnotationPresent(Author.class)) {
            //獲得該元素指定注解
            Author author = method.getAnnotation(Author.class);
            System.out.println("Author is " + author.value());
        }
    }
}

}```

首先通過(guò)反射獲得制定類中的所有方法融师,遍歷所有方法,找出其中含有制定注解的方法蚁吝,在通過(guò)getAnnotation方法獲得指定注解旱爆,進(jìn)而可以獲得注解信息。

需要用到的幾個(gè)方法:

//判斷是否被指定注解標(biāo)注
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) 

//返回該元素所有注解
public Annotation[] getAnnotations() 

//返回該元素指定注解
public <T extends Annotation> T getAnnotation(Class<T> annotationClass)```

這樣我們就完成了通過(guò)反射獲得運(yùn)行時(shí)注解窘茁。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末怀伦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子山林,更是在濱河造成了極大的恐慌房待,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異桑孩,居然都是意外死亡拜鹤,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門流椒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)敏簿,“玉大人,你說(shuō)我怎么就攤上這事宣虾」咴#” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵绣硝,是天一觀的道長(zhǎng)蜻势。 經(jīng)常有香客問(wèn)我,道長(zhǎng)鹉胖,這世上最難降的妖魔是什么握玛? 我笑而不...
    開(kāi)封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮次员,結(jié)果婚禮上败许,老公的妹妹穿的比我還像新娘。我一直安慰自己淑蔚,他們只是感情好市殷,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著刹衫,像睡著了一般醋寝。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上带迟,一...
    開(kāi)封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天音羞,我揣著相機(jī)與錄音,去河邊找鬼仓犬。 笑死嗅绰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的搀继。 我是一名探鬼主播窘面,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼叽躯!你這毒婦竟也來(lái)了财边?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤点骑,失蹤者是張志新(化名)和其女友劉穎酣难,沒(méi)想到半個(gè)月后谍夭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡憨募,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年紧索,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馋嗜。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡齐板,死狀恐怖吵瞻,靈堂內(nèi)的尸體忽然破棺而出葛菇,到底是詐尸還是另有隱情,我是刑警寧澤橡羞,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布眯停,位于F島的核電站,受9級(jí)特大地震影響卿泽,放射性物質(zhì)發(fā)生泄漏莺债。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一签夭、第九天 我趴在偏房一處隱蔽的房頂上張望齐邦。 院中可真熱鬧,春花似錦第租、人聲如沸措拇。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)丐吓。三九已至,卻和暖如春趟据,著一層夾襖步出監(jiān)牢的瞬間券犁,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工汹碱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粘衬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓咳促,卻偏偏與公主長(zhǎng)得像稚新,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子等缀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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