java注解——注解詳解和自定義注解

在上一篇文章中,我們介紹了注解(Annotation)的相關(guān)概念,對于 java1.5 引入的這種新特性,我們可以稱其為一種特殊的注釋。之所以說它特殊是因?yàn)椴煌谄胀ㄗ⑨?code>(comment)只能存在于源碼涝滴,而且還能在程序的編譯期跟運(yùn)行期中存在,會(huì)最終編譯成一個(gè).class文件。理所應(yīng)當(dāng)歼疮,注解會(huì)比普通注解起到更多的作用杂抽。
注解為我們在代碼中添加信息提供了一種形式化的方法,使我們可以在稍后某個(gè)時(shí)刻方便地使用這些數(shù)據(jù)(通過 解析注解 來使用這些數(shù)據(jù))韩脏。要想深入的理解并使用注解缩麸,必須能定義自己的注解,所以了解java提供的注解定義語法就非常重要了赡矢。
java.lang.annotation中包含所有定義自定義注解所需用到的元注解接口杭朱。比如接口java.lang.annotation.Annotation是所有注解都繼承的接口,并且是自動(dòng)繼承,不需要定義時(shí)指定吹散,類似于所有類都自動(dòng)繼承Object弧械。首先我們先來了解什么是元注解


元注解

元注解是 Java 本身提供空民,是專門用來定義注解的注解刃唐。被用來提供對其他注解類型作說明。Java提供了四個(gè)標(biāo)準(zhǔn)的元注解類型:

  • @Target,
  • @Retention,
  • @Documented,
  • @Inherited
@Target

@Target標(biāo)識(shí) Annotation 可以被使用在什么地方界轩。
使用方式:@Target(ElementType.METHOD)画饥。其可能的 ElementType 取值包括:

  • CONSTRUCTOR --> 構(gòu)造器(構(gòu)造函數(shù))的聲明
  • FIELD ---> 域聲明,包括 ENUM(枚舉)實(shí)例
  • LOCAL_VIRIEBLE ---> 局部變量聲明
  • METHOD ---> 方法聲明
  • PACKAGE ---> 包聲明
  • PARAMETER ---> 參數(shù)聲明
  • *TYPE ---> 類浊猾,接口聲明抖甘。包括注解類型和ENUM類型
@Retention

決定了 Annotation 的生命周期,即被保留的時(shí)間長短或者說在什么范圍內(nèi)有效与殃。Annotation 一共有三種生命周期单山,有的注解只出現(xiàn)在源代碼中;有的注解被被編譯在class文件中幅疼,但被虛擬機(jī)忽略;有的則是被虛擬機(jī)加載昼接,一直到程序運(yùn)行都還存在爽篷。
使用方式:@Retention(RetentionPolicy = RUNTIME)。其可能的 **RetentionPolicy ** 取值包括:

  • SOURCE -> 在源文件中有效(即源文件保留)
  • CLASS -> 在class文件中有效(即class保留)
  • RUNTIME -> 在運(yùn)行時(shí)有效(即運(yùn)行時(shí)保留)
@Documented

描述 Annotation 應(yīng)該被作為被標(biāo)注的程序成員的公共API慢睡,因此可以被例如javadoc此類的工具文檔化逐工。Documented是一個(gè)標(biāo)記注解,沒有成員漂辐。被例如javadoc此類的工具文檔泪喊。

@Inherited

這也是一個(gè)標(biāo)記注解。@Inherited 闡述了某個(gè)被標(biāo)注的類型是被繼承的髓涯。被標(biāo)注過的 class 的子類所繼承袒啼。類并不從它所實(shí)現(xiàn)的接口繼承 Annotation,方法并不從它所重載的方法繼承 Annotation。
當(dāng)使用@Inherited類型標(biāo)注的 Annotation 的 Retention 是RetentionPolicy.RUNTIME蚓再,則反射API增強(qiáng)了這種繼承性滑肉。如果我們使用java.lang.reflect去查詢一個(gè)@Inherited annotation類型的annotation時(shí),反射代碼檢查將展開工作:檢查class和其父類摘仅,直到發(fā)現(xiàn)指定的annotation類型被發(fā)現(xiàn)靶庙,或者到達(dá)類繼承結(jié)構(gòu)的頂層。


在本文的開頭我們就說過娃属,定義注解時(shí)會(huì)自動(dòng)繼承java.lang.annotation.Annotation接口六荒。同時(shí)還要注意的是,在定義注解時(shí)不能繼承其他注解和接口矾端。
注解的定義相對簡單掏击,有點(diǎn)類似于定義接口:

public @interface TestAnnotation {
      String field1() default "it's empty"; //default 設(shè)置默認(rèn)值
}

其中的每個(gè)方法都相當(dāng)于聲明了一個(gè)配置參數(shù),參數(shù)的名稱就是方法名须床,參數(shù)的類型就是返回值類型铐料。在自定義注解時(shí)有一些注意事項(xiàng):

  1. 方法(配置參數(shù))只能用 public 或者 默認(rèn)(default)這兩種訪問權(quán)限修飾。
  2. 方法(配置參數(shù))的返回值支持類型只包括以下幾種:
    • 所有的數(shù)據(jù)類型(int豺旬,float钠惩,boolean,byte族阅,double篓跛,char,long坦刀,short
    • String類型
    • Class類型
    • enum類型
    • Annotation(注解)類型
    • 以上所有類型的數(shù)組
  3. 注解中有一個(gè)特殊的存在:value愧沟。當(dāng)注解中只有一個(gè)方法(配置參數(shù))時(shí),最好是將方法命名為 value鲤遥。這樣在使用注解時(shí)沐寺,就可以省略參數(shù)名,比如之后的例子:@Owner盖奈。
簡單的自定義注解使用例子
/**
* book相關(guān)的注解混坞。
* 包括兩個(gè)參數(shù):名稱和頁數(shù)
**/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BookInfo {
      public String name() default "";
      public int pageSize() default 0;
}
/**
* 擁有人注解
* 只有一個(gè)參數(shù),命名為 value
**/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Owner {
      public String value() default "";
}
public class UserBook {
      @BookInfo(name = "EngLish", pageSize = 80)
      public EngLish engLish;

      @Owner("testName")
      public String ownerName;
}

注解元素必須有確定的值钢坦,要么在定義注解的默認(rèn)值中指定究孕,要么在使用注解時(shí)指定,非基本類型的注解元素的值不可為null爹凹。
在注解的語法部分中厨诸,對于特殊的 value 參數(shù),當(dāng)只指定該參數(shù)時(shí)禾酱,可以省略參數(shù)名和等號(hào)微酬。這也是上面說的注意事項(xiàng)中第三點(diǎn)的原因

根據(jù)注解參數(shù)的不同绘趋,可以將注解分為以下幾類:

  • 標(biāo)注注解。沒有參數(shù)成員得封,通過判斷該注解是否存在獲得相關(guān)的信息
  • 單值注解埋心。只有一個(gè)參數(shù)成員,一般為 value忙上,這樣可以省略參數(shù)名和等號(hào)
  • 完整注解
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拷呆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子疫粥,更是在濱河造成了極大的恐慌茬斧,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梗逮,死亡現(xiàn)場離奇詭異项秉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)慷彤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門娄蔼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人底哗,你說我怎么就攤上這事岁诉。” “怎么了跋选?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵涕癣,是天一觀的道長。 經(jīng)常有香客問我前标,道長坠韩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任炼列,我火速辦了婚禮只搁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘俭尖。我一直安慰自己须蜗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布目溉。 她就那樣靜靜地躺著,像睡著了一般菱农。 火紅的嫁衣襯著肌膚如雪缭付。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天循未,我揣著相機(jī)與錄音陷猫,去河邊找鬼秫舌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛绣檬,可吹牛的內(nèi)容都是我干的足陨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼娇未,長吁一口氣:“原來是場噩夢啊……” “哼墨缘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起零抬,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤镊讼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后平夜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝶棋,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年忽妒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玩裙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡段直,死狀恐怖吃溅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情坷牛,我是刑警寧澤罕偎,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站京闰,受9級(jí)特大地震影響颜及,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蹂楣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一俏站、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧痊土,春花似錦肄扎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至酌呆,卻和暖如春衡载,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背隙袁。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工痰娱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留弃榨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓梨睁,卻偏偏與公主長得像鲸睛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子坡贺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

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