java注解初探

我們IDE編程時(shí)經(jīng)常會(huì)自動(dòng)給我們添加Override佩憾、Deprecated等以及三方框架注解哮伟,這些注解是怎么定義以及工作的,我們?cè)撛趺醋远x注解妄帘,這些可能是一個(gè)入門程序猿所不了解的,這篇文章以及下一篇如何編寫自定義注解將一點(diǎn)點(diǎn)的介紹注解概念以及如何自定義注解池凄,希望能給一些對(duì)注解有困惑的開發(fā)一點(diǎn)幫助

基本概念

Annotation(注解)就是Java提供了一種元程序中的元素關(guān)聯(lián)任何信息和著任何元數(shù)據(jù)(metadata)的途徑和方法抡驼,Annotion是一個(gè)接口,程序可以通過(guò)反射來(lái)獲取指定程序元素的Annotion對(duì)象肿仑,然后通過(guò)Annotion對(duì)象來(lái)獲取注解里面的元數(shù)據(jù)致盟。
  Annotation(注解)是JDK5.0及以后版本引入的。它可以用于創(chuàng)建文檔尤慰,跟蹤代碼中的依賴性馏锡,甚至執(zhí)行基本編譯時(shí)檢查。從某些方面看伟端,annotation就像修飾符一樣被使用杯道,并應(yīng)用于包、類 型责蝠、構(gòu)造方法党巾、方法萎庭、成員變量、參數(shù)齿拂、本地變量的聲明中驳规。這些信息被存儲(chǔ)在Annotation的“name=value”結(jié)構(gòu)對(duì)中。
  Annotation的成員在Annotation類型中以無(wú)參數(shù)的方法的形式被聲明署海。其方法名和返回值定義了該成員的名字和類型吗购。在此有一個(gè)特定的默認(rèn)語(yǔ)法:允許聲明任何Annotation成員的默認(rèn)值:一個(gè)Annotation可以將name=value對(duì)作為沒有定義默認(rèn)值的Annotation成員的值,當(dāng)然也可以使用name=value對(duì)來(lái)覆蓋其它成員默認(rèn)值砸狞。這一點(diǎn)有些近似類的繼承特性巩搏,父類的構(gòu)造函數(shù)可以作為子類的默認(rèn)構(gòu)造函數(shù),但是也可以被子類覆蓋趾代。
  Annotation能被用來(lái)為某個(gè)程序元素(類贯底、方法、成員變量等)關(guān)聯(lián)任何的信息撒强。需要注意的是禽捆,這里存在著一個(gè)基本的規(guī)則:Annotation不能影響程序代碼的執(zhí)行,無(wú)論增加飘哨、刪除 Annotation胚想,代碼都始終如一的執(zhí)行。

首先看下我們最長(zhǎng)用到的JDK內(nèi)置注解

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

Override注解又使用了注解芽隆?沒錯(cuò)浊服,@Target和@Retention是元注解(用于給其注解其他注解,一般自定義注解都要使用)胚吁,到這里我們可以給注解分下類:
根據(jù)注解使用方法和用途牙躺,我們可以將annotation分三類:
1、系統(tǒng)注解:JDK提供了三個(gè)系統(tǒng)注解Override(標(biāo)記此方法是覆蓋了父類的方法)腕扶、Deprecated(用于標(biāo)記方法等過(guò)時(shí)孽拷,一般都會(huì)有新的API提供)、SuppressWarnnings(用于通知java編譯器禁止特定的編譯警告)
2半抱、元注解:Java5.0定義了4個(gè)標(biāo)準(zhǔn)的meta-annotation類型
①@Target:用于說(shuō)明Annotation所修飾的范圍脓恕,系統(tǒng)代碼如下

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

ElementType是個(gè)枚舉類型,取值有:
1.CONSTRUCTOR:用于描述構(gòu)造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部變量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述參數(shù)
7.TYPE:用于描述類窿侈、接口(包括注解類型) 或enum聲明
②@Retention:定義Annotation被保留的時(shí)間長(zhǎng)短即注解生命周期限制

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

RetentionPolicy也是個(gè)枚舉類型炼幔,取值有:
1.SOURCE:在源文件中有效(即源文件保留,被編譯器丟棄)
2.CLASS:在class文件中有效(即class保留史简,被編譯但虛擬機(jī)忽略)
3.RUNTIME:在運(yùn)行時(shí)有效(即運(yùn)行時(shí)保留乃秀,class裝載的時(shí)候讀取)

③@Documented:用于描述其它類型的annotation應(yīng)該被作為被標(biāo)注的程序成員的公共API,因此可以被例如javadoc此類的工具文檔化

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

④@Inherited:用于標(biāo)記注解是被繼承的环形,如果一個(gè)使用了@Inherited修飾的annotation類型被用于一個(gè)class策泣,則這個(gè)annotation將被用于該class的子類

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

3、自定義注解:自定義注解一般包含編譯注解和運(yùn)行時(shí)注解抬吟,根據(jù)系統(tǒng)提供API以及相關(guān)機(jī)制在編譯或者運(yùn)行時(shí)獲取想要的數(shù)據(jù)萨咕,自定義注解形式和系統(tǒng)注解以及元注解一樣,下文會(huì)有自定義注解的Demo火本。

從上面的元注解來(lái)看危队,注解又分為:
1、標(biāo)記注解钙畔,比如@Override茫陆、@Inherited、@Documented擎析。這類注解是沒有元素的簿盅,用于標(biāo)記元素特性比如過(guò)時(shí)、覆蓋父類方法等
2揍魂、單值注解桨醋,只有一個(gè)元素的注解,比如@Target现斋、@Retention等
3喜最、完整注解 ,除了①和②的所有注解

自定義注解

為了下面我們自定義注解Demo庄蹋,我們先了解一下自定義注解的寫法瞬内。使用@interface自定義注解時(shí),自動(dòng)繼承了java.lang.annotation.Annotation接口限书,由編譯程序自動(dòng)完成其他細(xì)節(jié)虫蝶。在定義注解時(shí),不能繼承其他的注解或接口蔗包。@interface用來(lái)聲明一個(gè)注解秉扑,其中的每一個(gè)方法實(shí)際上是聲明了一個(gè)配置參數(shù)。方法的名稱就是參數(shù)的名稱调限,返回值類型就是參數(shù)的類型(返回值類型只能是基本類型、Class误澳、String耻矮、enum、Annotation以及這些類型的數(shù)組)忆谓●勺埃可以通過(guò)default來(lái)聲明參數(shù)的默認(rèn)值。

注解元素定義形式如:

public @interface 注解名 {定義體}//public 可以省略
public String name() default "fieldName";//元素定義樣式</pre>

使用形式:

@注解名(name1= value1,name2 = value2)

單值注解定義和使用還有簡(jiǎn)寫方式:

元素定義:

String value() default “value”

使用形式:

@注解名(value)

定義注解和使用注解都很容易,關(guān)鍵還是要處理注解哨免,如果沒有處理注解的方法那么注解就僅僅相當(dāng)于注釋了茎活。所以創(chuàng)建注解處理器是很重要的,獲取注解之前我們肯定要先獲取注解作用的Target比如:
Class:類定義
Constructor:構(gòu)造器定義
Field:類的成員變量
Method:類中的方法
Package:類的包定義(有點(diǎn)不懂@**@)
這幾個(gè)都是AnnotatedElement接口實(shí)現(xiàn)類琢唾,運(yùn)行時(shí)注解可以通過(guò)java.lang.reflect包下的反射API運(yùn)行時(shí)獲取载荔,含的獲取注解的方法如下:
方法1:<T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回改程序元素上存在的、指定類型的注解采桃,如果該類型注解不存在懒熙,則返回null。
  方法2:Annotation[] getAnnotations():返回該程序元素上存在的所有注解普办。
  方法3:boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判斷該程序元素上是否包含指定類型的注解工扎,存在則返回true,否則返回false.
  方法4:Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注釋衔蹲。與此接口中的其他方法不同肢娘,該方法將忽略繼承的注釋。(如果沒有注釋直接存在于此元素上舆驶,則返回長(zhǎng)度為零的一個(gè)數(shù)組橱健。)該方法的調(diào)用者可以隨意修改返回的數(shù)組;這不會(huì)對(duì)其他調(diào)用者返回的數(shù)組產(chǎn)生任何影響贞远。

由于篇幅的原因自定義注解(編譯時(shí)注解以及運(yùn)行時(shí)注解Demo)將在下一篇博客如何編寫自定義注解中介紹

最后用一張思維導(dǎo)圖來(lái)總結(jié)一下注解
image

參考文獻(xiàn):深入理解java注解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末畴博,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蓝仲,更是在濱河造成了極大的恐慌俱病,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件袱结,死亡現(xiàn)場(chǎng)離奇詭異亮隙,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)垢夹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門溢吻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人果元,你說(shuō)我怎么就攤上這事促王。” “怎么了而晒?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵蝇狼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我倡怎,道長(zhǎng)迅耘,這世上最難降的妖魔是什么贱枣? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮颤专,結(jié)果婚禮上纽哥,老公的妹妹穿的比我還像新娘。我一直安慰自己栖秕,他們只是感情好春塌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著累魔,像睡著了一般摔笤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上垦写,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天吕世,我揣著相機(jī)與錄音,去河邊找鬼梯投。 笑死命辖,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的分蓖。 我是一名探鬼主播尔艇,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼么鹤!你這毒婦竟也來(lái)了终娃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蒸甜,失蹤者是張志新(化名)和其女友劉穎棠耕,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柠新,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡窍荧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恨憎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蕊退。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖憔恳,靈堂內(nèi)的尸體忽然破棺而出瓤荔,到底是詐尸還是另有隱情,我是刑警寧澤钥组,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布茉贡,位于F島的核電站,受9級(jí)特大地震影響者铜,放射性物質(zhì)發(fā)生泄漏腔丧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一作烟、第九天 我趴在偏房一處隱蔽的房頂上張望愉粤。 院中可真熱鬧,春花似錦拿撩、人聲如沸衣厘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)影暴。三九已至,卻和暖如春探赫,著一層夾襖步出監(jiān)牢的瞬間型宙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工伦吠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留妆兑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓毛仪,卻偏偏與公主長(zhǎng)得像搁嗓,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子箱靴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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

  • 本文章涉及代碼已放到github上annotation-study 1.Annotation為何而來(lái) What:A...
    zlcook閱讀 29,161評(píng)論 15 116
  • 什么是注解(Annotation):Annotation(注解)就是Java提供了一種元程序中的元素關(guān)聯(lián)任何信息和...
    九尾喵的薛定諤閱讀 3,168評(píng)論 0 2
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理腺逛,服務(wù)發(fā)現(xiàn),斷路器衡怀,智...
    卡卡羅2017閱讀 134,659評(píng)論 18 139
  • 內(nèi)容概要 Annotation的概念 Annotation的作用 Annotation的分類 系統(tǒng)內(nèi)置注解 元注解...
    DevinZhang閱讀 4,170評(píng)論 0 28
  • 睡吧睡吧 敲下這一句之后把手機(jī)拿開 然后又點(diǎn)開 滑一下記錄 點(diǎn)一下微博 不對(duì)勁 不對(duì)勁 越憋越難受 翻來(lái)覆去 明明...
    博士說(shuō)閱讀 236評(píng)論 0 0