Java注解Annotation小結(jié)

對(duì)于java注解我之前就是僅僅拿來(lái)使用,也沒(méi)有深究其背后的細(xì)節(jié)。但新工作使用新框架,原本一些清晰透明的配置信息,被公司公共平臺(tái)開(kāi)發(fā)的組件進(jìn)行了抽離,并通過(guò)注解的方式進(jìn)行了簡(jiǎn)化。雖然結(jié)果上是簡(jiǎn)化了開(kāi)發(fā),但卻進(jìn)一步強(qiáng)化了我內(nèi)心對(duì)技術(shù)成長(zhǎng)的焦慮。

因?yàn)楹?jiǎn)化了開(kāi)發(fā),讓我覺(jué)得不可捉摸,所以我覺(jué)得自己有必要帶著疑問(wèn)首先要把注解搞清楚,然后后面再抽時(shí)間把組件背后也即是APT的部分搞明白。這樣關(guān)于新公司簡(jiǎn)化開(kāi)發(fā)省去的部分自己才能真正做到心知肚明。我相信如此一步步來(lái),才能幫助自己實(shí)現(xiàn)技術(shù)的成長(zhǎng)與提升。


1 Java注解核心要義概述

Java注解是從jdk5開(kāi)始出現(xiàn)的,它是代碼里面的特殊標(biāo)記,這些標(biāo)記可以在編譯、類(lèi)加載、運(yùn)行時(shí)被讀取,并執(zhí)行相應(yīng)的處理。通過(guò)使用注解,開(kāi)發(fā)人員可以在不改變?cè)羞壿嫷那闆r下,在源文件中嵌入一些補(bǔ)充的信息,比如代碼分析工具、開(kāi)發(fā)工具和部署工具等。

Java注解作為一種修飾符,它可以用來(lái)修飾包、類(lèi)、構(gòu)造器、方法、成員變量、參數(shù)、局部變量的聲明,在修飾的同時(shí)也可以設(shè)置元數(shù)據(jù)(name=value)。

Java注解(Annotation)是一個(gè)接口,程序可以通過(guò)反射來(lái)獲取指定程序元素的Annotation對(duì)象,然后通過(guò)Annotation對(duì)象來(lái)取得注解里的元數(shù)據(jù)。

值得指出的是,Annotation不影響程序代碼的執(zhí)行,無(wú)論增加、刪除Annotation,代碼都會(huì)始終如一地執(zhí)行。如果希望讓程序中的Annotation在運(yùn)行時(shí)起一定的作用,只有通過(guò)某種配套的工具對(duì)Annotation中的信息進(jìn)行訪問(wèn)和處理,訪問(wèn)和處理Annotation的工具統(tǒng)稱(chēng)APT(Annotation Processing Tool)。

2 注解分類(lèi)

根據(jù)Annotation是否包含成員變量,可以把Annotation分為兩類(lèi):

  • 標(biāo)記Annotation:沒(méi)有定義成員變量,是僅利用自身的存在與否提供信息,比如注解@Test、@Override。
  • 元數(shù)據(jù)Annotation:包含成員變量。

下面介紹常見(jiàn)的注解:

2.1 java.lang下5個(gè)基本標(biāo)記Annotation
  • @Override:限定重寫(xiě)父類(lèi)方法,作用就是告訴編譯器檢查被修飾的這個(gè)方法,保證父類(lèi)要包含一個(gè)被該方法重寫(xiě)的方法,否則就會(huì)編譯出錯(cuò)。主要就是幫助程序員避免一些低級(jí)錯(cuò)誤。
  • @Deprecated:標(biāo)示已過(guò)時(shí)
  • @SuppressWarnings:抑制編譯器警告。
  • @SafeVarargs:java7的堆污染警告。當(dāng)把一個(gè)不帶泛型的對(duì)象賦給一個(gè)帶泛型的變量時(shí),往往會(huì)發(fā)生這種堆污染;對(duì)于形參個(gè)數(shù)可變的方法,如果形參類(lèi)型又是泛型的話,就更容易導(dǎo)致堆污染。
  • @FunctionalInterface:java8的函數(shù)式接口,用來(lái)指定某個(gè)接口必須是函數(shù)式接口。也就是告訴編譯器檢查這個(gè)接口,保證該接口只能包含一個(gè)抽象方法,否則就會(huì)編譯出錯(cuò)。
2.2 jdk的元Annotation
  • @Retention:只能用于修飾Annotation定義,用于指定被修飾的Annotation可以保留多長(zhǎng)時(shí)間。

    @Retention包含一個(gè)RetentionPolicy類(lèi)型的value成員變量,value成員變量的值只能是如下三個(gè):
    (1) RetentionPolicy.CLASS(注解記錄在class文件中,程序運(yùn)行時(shí),jvm不可獲取注解信息);
    (2)RetentionPolicy.RUNTIME(注解記錄在class文件中,程序運(yùn)行時(shí),jvm可獲取注解信息) ;
    (3)RetentionPolicy.SOURCE(只保留在源代碼中,編譯器直接丟棄這種注解)。

  • @Target:只能用于修飾Annotation定義,用于指定被修飾的Annotation可以用于修飾那些程序單元。

    該成員變量的值只能是如下幾個(gè):
    (1)ElementType.ANNOTATION_TYPE(只能修飾注解);
    (2)ElementType.CONSTRUCTOR(只能修飾構(gòu)造器);
    (3)ElementType.FIELD(只能修飾成員變量);
    (4)ElementType.LOCAL_VARIABLE(只能修飾局部變量);
    (5)ElementType.METHOD(只能修飾方法);
    (6)ElementType.PACKAGE(只能修飾包定義);
    (7)ElementType.PARAMETER(只能修飾參數(shù));
    (8)ElementType.TYPE(只能修飾類(lèi)、接口或枚舉定義)。

  • @Documented:用于指定被該元Annotation修飾的Annotation類(lèi)將被javadoc工具提取成文檔。

  • @Inherited:用于指定被它修飾的注解具有繼承性,父類(lèi)被該注解修飾,子類(lèi)也自動(dòng)被該注解修飾。

3 自定義注解

  • (1)定義新的注解類(lèi)型使用@interface關(guān)鍵字;
  • (2)新定義的注解可以帶成員變量,成員變量以無(wú)形參的方法形式來(lái)聲明,其方法名和返回值定義了該成員變量的名字和類(lèi)型。
    -(3) 可以為注解的成員變量指定初始值即默認(rèn)值,指定成員變量的初始值可以使用default關(guān)鍵字。
public @interface Mytag{
  String name() default "xiaoming";
  int age();
}

4 提取注解信息

使用Annotation修飾了類(lèi)、方法、成員變量等成員之后,這些注解不會(huì)自己生效,必須由開(kāi)發(fā)者提供相應(yīng)的工具來(lái)提取并處理注解信息。從java5開(kāi)始,java.lang.reflect包所提供的反射API增加了讀取運(yùn)行時(shí)注解的能力。

至于APT工具的開(kāi)發(fā)實(shí)例,后面深挖學(xué)習(xí)之后,再做進(jìn)一步分享。

提取注解信息-后話

作為一個(gè)開(kāi)發(fā)人員,我之前很少使用自定義注解,所以對(duì)于讀取注解之前是很不熟悉。而經(jīng)過(guò)一段時(shí)間的學(xué)習(xí)之后,我對(duì)于讀取使用注解有了新的思考。尤其是對(duì)于使用Spring開(kāi)發(fā)框架的我們,有著很好的優(yōu)勢(shì),因?yàn)镾pring給我們提供了很多方式可以來(lái)讀取運(yùn)行時(shí)中注解。

比如,web接口中對(duì)于加在方法上的注解,我們可以通過(guò)使用攔截器的方式進(jìn)行讀取并進(jìn)行相應(yīng)操作。另外對(duì)于加在非私有方法上的注解,我們可以使用Spring AOP切面編程的方式進(jìn)行讀取。對(duì)于加載類(lèi)上的注解,我們可以在對(duì)象完成初始化之后,通過(guò)借助處理器BeanPostProcessor來(lái)讀取注解。

這些讀取使用方式,都是我在工作中實(shí)際應(yīng)用到的。在這里記錄分享一下,也期待能夠給有緣的同學(xué)帶來(lái)一些啟發(fā)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容