注解的那些事兒(二)| 如何自定義注解

自定義注解是自己寫框架的必備技能副编,使用注解能極大地提升開發(fā)效率煮寡,因此自定義注解是一個高級開發(fā)者必備的技能。

要自定義注解趾诗,首先需要了解一個注解的構(gòu)成部分蜡感。

一個注解大致可以分為三個部分:注解體、元注解、注解屬性郑兴。

image

在在這三個主要組成部分中犀斋,注解體指定了注解的名字,而元注解則標(biāo)記了該注解的使用場景情连、留存時間等信息叽粹,而注解屬性則指明該注解擁有的屬性。

注解體

注解體是最簡單的一個組成部分蒙具,只需要像實例中一樣有樣學(xué)樣即可球榆。與接口的聲明唯一的不同是在 interface 關(guān)鍵字前多了一個 @ 符號。

//聲明了一個名為sweet的注解體
@Retention(RetentionPolicy.RUNTIME) 
public @interface sweet{
}

元注解

元注解(meta-annotation)本身也是一個注解禁筏,用來標(biāo)記普通注解的存留時間持钉、使用場景、繼承屬性篱昔、文檔生成信息每强。

元注解是一個特殊的注解,它是 Java 源碼中就自帶的注解州刽。在Java 中只有四個元注解空执,它們分別是:@Target、@Retention穗椅、@Documented辨绊、@Inherited。

@Target注解

Target 注解限定了該注解的使用場景匹表。

它有下面這些取值:

  • ElementType.ANNOTATION_TYPE 可以給一個注解進(jìn)行注解
  • ElementType.CONSTRUCTOR 可以給構(gòu)造方法進(jìn)行注解
  • ElementType.FIELD 可以給屬性進(jìn)行注解
  • ElementType.LOCAL_VARIABLE 可以給局部變量進(jìn)行注解
  • ElementType.METHOD 可以給方法進(jìn)行注解
  • ElementType.PACKAGE 可以給一個包進(jìn)行注解
  • ElementType.PARAMETER 可以給一個方法內(nèi)的參數(shù)進(jìn)行注解
  • ElementType.TYPE 可以給一個類型進(jìn)行注解门坷,比如類、接口袍镀、枚舉
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) 
public @interface Autowired { 
    boolean required() default true;
}

在上面 Autowire的 注解中默蚌,其 Target 注解的值為 CONSTRUCTOR、METHOD苇羡、PARAMETER绸吸、FIELD、ANNOTATION_TYPE 這 5 個值设江。這表示 Autowired 注解只能在構(gòu)造方法锦茁、方法、方法形參绣硝、屬性蜻势、類型這 5 種場景下使用。

@Retention注解

Retention 注解用來標(biāo)記這個注解的留存時間鹉胖。

它其有四個可選值:

  • RetentionPolicy.SOURCE握玛。注解只在源碼階段保留够傍,在編譯器進(jìn)行編譯時它將被丟棄忽視。
  • RetentionPolicy.CLASS挠铲。注解只被保留到編譯進(jìn)行的時候冕屯,它并不會被加載到 JVM 中。
  • RetentionPolicy.RUNTIME拂苹。注解可以保留到程序運行的時候安聘,它會被加載進(jìn)入到 JVM 中,所以在程序運行時可以獲取到它們瓢棒。
@Retention(RetentionPolicy.RUNTIME) 
public @interface Autowired { 
    boolean required() default true;
}

在上面 Autowire的 注解中浴韭,其 Retention 注解的值為 RetentionPolicy.RUNTIME,說明該注解會保留到程序運行的時候脯宿。

@Documented

@ Documented 注解表示將注解信息寫入到 javadoc 文檔中念颈。

在默認(rèn)情況下,我們的注解信息是不會寫入到 Javadoc 文檔中的连霉。但如果該注解有 @Documented 標(biāo)識榴芳,那么該注解信息則會寫入到 javadoc 文檔中。

例如在下面這個例子中跺撼,我們聲明了一個 @Spicy 的注解窟感,沒有 @Documented 元注解。

public @interface Spicy {
    String spicyLevel();
}

聲明一個 @Sweet 注解歉井,有 @Documented 元注解柿祈。

@Documented
public @interface Sweet {
    String sweetLevel();
}

接下來寫一個 SweetDemo 類,類中的 sweetWithDoc 方法使用 @Sweet 注解哩至,spicyWithoutDoc 方法使用 @Spicy 注解谍夭。

public class SweetDemo {
    public static void main(String arg[]) {
        new SweetDemo().sweetWithDoc();
        new SweetDemo().spicyWithoutDoc();
    }
    @Sweet (sweetLevel="Level.05")
    public void sweetWithDoc() {
        System.out.printf("sweet With Doc.");
    }
    @Spicy (spicyLevel="Level.04")
    public void spicyWithoutDoc() {
        System.out.printf("spicy Without Doc.");
    }
}

最后我們使用 Javadoc 命令去生成對應(yīng)的 JavaDoc 文檔,打開文檔你會看到:sweetWithDoc方法上面有一個注解信息憨募,而 spicyWithoutDoc 方法上卻沒有注解信息。

image

這個就是 @Documented 這個元注解的作用袁辈。

@Inherited

@ Inherited注解標(biāo)識子類將繼承父類的注解屬性菜谣。

在下面的例子中,我們聲明了一個 Sweet 注解晚缩,接著在 Peach 類使用了 @Sweet 注解尾膊,但是并沒有在 RedPeach 類使用該注解。

//聲明一個Sweet注解荞彼,標(biāo)識甜味冈敛。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Sweet {}
//桃子有甜味
@Sweet
public class Peach {}
//紅色的水蜜桃
public class RedPeach extends Peach {}

雖然我們沒在 RedPeach 類上使用了 @Sweet 注解,但是我們在 Sweet 注解聲明中使用了 @Inherited 注解鸣皂,所以 RedPeach 繼承了 Peach 的 @Sweet 注解抓谴。

注解屬性

注解屬性類似于類方法的聲明暮蹂,注解屬性里有三部分信息,分別是:屬性名癌压、數(shù)據(jù)類型仰泻、默認(rèn)值。

在 @Autowired 注解中就聲明了一個名為 required 的 boolean 類型數(shù)據(jù)滩届,其默認(rèn)值是 true集侯。

public @interface Autowired {
    boolean required() default true;
}

需要注意的是,注解中定義的屬性帜消,它的數(shù)據(jù)類型必須是 8 種基本數(shù)據(jù)類型(byte棠枉、short、int泡挺、long辈讶、float、double粘衬、boolean荞估、char)或者是類、接口稚新、注解及它們的數(shù)組勘伺。

總結(jié)

一個注解大致可以分為三個部分:注解體、元注解褂删、注解屬性飞醉。在這三個主要組成部分中:注解體指定了注解的名字、元注解則標(biāo)記了該注解的使用信息屯阀,注解屬性指明注解的屬性缅帘。

image

學(xué)習(xí)注解只要知道這三個部分就夠了,至于那些繁雜的屬性难衰,就用下面這張圖來解決吧钦无。用到的時候翻一翻,查一查盖袭,足矣失暂!

image

原文可見:注解的那些事兒(二)| 如何自定義注解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市鳄虱,隨后出現(xiàn)的幾起案子弟塞,更是在濱河造成了極大的恐慌,老刑警劉巖拙已,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件决记,死亡現(xiàn)場離奇詭異,居然都是意外死亡倍踪,警方通過查閱死者的電腦和手機系宫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門索昂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笙瑟,你說我怎么就攤上這事楼镐。” “怎么了往枷?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵框产,是天一觀的道長。 經(jīng)常有香客問我错洁,道長秉宿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任屯碴,我火速辦了婚禮描睦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘导而。我一直安慰自己忱叭,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布今艺。 她就那樣靜靜地躺著韵丑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪虚缎。 梳的紋絲不亂的頭發(fā)上撵彻,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音实牡,去河邊找鬼陌僵。 笑死,一個胖子當(dāng)著我的面吹牛创坞,可吹牛的內(nèi)容都是我干的碗短。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼题涨,長吁一口氣:“原來是場噩夢啊……” “哼豪椿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起携栋,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咳秉,沒想到半個月后婉支,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡澜建,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年向挖,在試婚紗的時候發(fā)現(xiàn)自己被綠了蝌以。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡何之,死狀恐怖跟畅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情溶推,我是刑警寧澤徊件,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站蒜危,受9級特大地震影響虱痕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜辐赞,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一部翘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧响委,春花似錦新思、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贝次,卻和暖如春崔兴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蛔翅。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工敲茄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人山析。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓堰燎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親笋轨。 傳聞我的和親對象是個殘疾皇子秆剪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345