Java 注解

1河狐、Annotation的工作原理:

JDK5.0中提供了注解的功能舱馅,允許開發(fā)者定義和使用自己的注解類型积糯。該功能由一個定義注解類型的語法和描述一個注解聲明的語法,讀取注解的API护戳,一個使用注解修飾的class文件和一個注解處理工具組成。

Annotation并不直接影響代碼的語義垂睬,但是他可以被看做是程序的工具或者類庫灸异。它會反過來對正在運(yùn)行的程序語義有所影響。

Annotation可以沖源文件羔飞、class文件或者在運(yùn)行時通過反射機(jī)制多種方式被讀取肺樟。

2、@Override注解:

java.lang注釋類型 Override@Target(value=METHOD)@Retention(value=SOURCE)public @interfaceOverride

表示一個方法聲明打算重寫超類中的另一個方法聲明逻淌。如果方法利用此注釋類型進(jìn)行注解但沒有重寫超類方法么伯,則編譯器會生成一條錯誤消息。

@Override注解表示子類要重寫父類的對應(yīng)方法卡儒。

Override是一個Marker annotation田柔,用于標(biāo)識的Annotation,Annotation名稱本身表示了要給工具程序的信息骨望。

下面是一個使用@Override注解的例子:

classA {privateString id;? ? A(String id){this.id = id;? ? }@OverridepublicString toString() {returnid;? ? }}

3硬爆、@Deprecated注解:

java.lang注釋類型 Deprecated@Documented@Retention(value=RUNTIME)public @interfaceDeprecated

用 @Deprecated 注釋的程序元素,不鼓勵程序員使用這樣的元素擎鸠,通常是因?yàn)樗芪kU或存在更好的選擇缀磕。在使用不被贊成的程序元素或在不被贊成的代碼中執(zhí)行重寫時,編譯器會發(fā)出警告。

@Deprecated注解表示方法是不被建議使用的袜蚕。

Deprecated是一個Marker annotation糟把。

下面是一個使用@Deprecated注解的例子:

classA?

{

privateString id;? ? A(String id){this.id = id;? ? }@Deprecatedpublicvoidexecute(){? ? ? ? System.out.println(id);? ? }publicstaticvoidmain(String[] args) {? ? ? ? A a =newA("a123");? ? ? ? a.execute();? ? }}

4、@SuppressWarnings注解:

java.lang注釋類型 SuppressWarnings@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})@Retention(value=SOURCE)public @interfaceSuppressWarnings

指示應(yīng)該在注釋元素(以及包含在該注釋元素中的所有程序元素)中取消顯示指定的編譯器警告牲剃。注意遣疯,在給定元素中取消顯示的警告集是所有包含元素中取消顯示的警告的超集。例如凿傅,如果注釋一個類來取消顯示某個警告缠犀,同時注釋一個方法來取消顯示另一個警告,那么將在此方法中同時取消顯示這兩個警告聪舒。

根據(jù)風(fēng)格不同夭坪,程序員應(yīng)該始終在最里層的嵌套元素上使用此注釋,在那里使用才有效过椎。如果要在特定的方法中取消顯示某個警告室梅,則應(yīng)該注釋該方法而不是注釋它的類。

@SuppressWarnings注解表示抑制警告疚宇。

下面是一個使用@SuppressWarnings注解的例子:

@SuppressWarnings("unchecked")publicstaticvoidmain(String[] args) {? ? List list =newArrayList();? ? list.add("abc");}

5亡鼠、自定義注解:

使用@interface自定義注解時,自動繼承了java.lang.annotation.Annotation接口敷待,由編譯程序自動完成其他細(xì)節(jié)间涵。在定義注解時,不能繼承其他的注解或接口榜揖。

自定義最簡單的注解:

public@interfaceMyAnnotation {}

使用自定義注解:

publicclassAnnotationTest2 {@MyAnnotationpublicvoidexecute(){? ? ? ? System.out.println("method");? ? }}

5.1勾哩、添加變量:

public@interfaceMyAnnotation {? ? String value1();}

使用自定義注解:

publicclassAnnotationTest2 {@MyAnnotation(value1="abc")publicvoidexecute(){? ? ? ? System.out.println("method");? ? }}

當(dāng)注解中使用的屬性名為value時,對其賦值時可以不指定屬性的名稱而直接寫上屬性值接口举哟;除了value意外的變量名都需要使用name=value的方式賦值思劳。

5.2、添加默認(rèn)值:

public@interfaceMyAnnotation {? ? String value1()default"abc";}

5.3妨猩、多變量使用枚舉:

public@interfaceMyAnnotation {? ? String value1()default"abc";? ? MyEnum value2()defaultMyEnum.Sunny;}enum MyEnum{? ? Sunny,Rainy}

使用自定義注解:

publicclassAnnotationTest2 {@MyAnnotation(value1="a", value2=MyEnum.Sunny)publicvoidexecute(){? ? ? ? System.out.println("method");? ? }}

5.4潜叛、數(shù)組變量:

public@interfaceMyAnnotation {? ? String[] value1()default"abc";}

使用自定義注解:

publicclassAnnotationTest2 {@MyAnnotation(value1={"a","b"})publicvoidexecute(){? ? ? ? System.out.println("method");? ? }}

6、設(shè)置注解的作用范圍:

@Documented@Retention(value=RUNTIME)@Target(value=ANNOTATION_TYPE)public @interfaceRetention

指示注釋類型的注釋要保留多久壶硅。如果注釋類型聲明中不存在 Retention 注釋威兜,則保留策略默認(rèn)為 RetentionPolicy.CLASS。

只有元注釋類型直接用于注釋時庐椒,Target 元注釋才有效椒舵。如果元注釋類型用作另一種注釋類型的成員,則無效约谈。

public enumRetentionPolicyextends Enum

注釋保留策略笔宿。此枚舉類型的常量描述保留注釋的不同策略犁钟。它們與 Retention 元注釋類型一起使用,以指定保留多長的注釋措伐。

CLASS編譯器將把注釋記錄在類文件中特纤,但在運(yùn)行時 VM 不需要保留注釋军俊。RUNTIME編譯器將把注釋記錄在類文件中侥加,在運(yùn)行時 VM 將保留注釋,因此可以反射性地讀取粪躬。SOURCE編譯器要丟棄的注釋担败。

@Retention注解可以在定義注解時為編譯程序提供注解的保留策略。

屬于CLASS保留策略的注解有@SuppressWarnings镰官,該注解信息不會存儲于.class文件提前。

6.1、在自定義注解中的使用例子:

@Retention(RetentionPolicy.CLASS)public@interfaceMyAnnotation {? ? String[] value1()default"abc";}

7泳唠、使用反射讀取RUNTIME保留策略的Annotation信息的例子:

java.lang.reflect? ? ? ? 接口AnnotatedElement所有已知實(shí)現(xiàn)類:? ? ? ? AccessibleObject, Class, Constructor, Field, Method, Package

表示目前正在此 VM 中運(yùn)行的程序的一個已注釋元素狈网。該接口允許反射性地讀取注釋。由此接口中的方法返回的所有注釋都是不可變并且可序列化的笨腥。調(diào)用者可以修改已賦值數(shù)組枚舉成員的訪問器返回的數(shù)組拓哺;這不會對其他調(diào)用者返回的數(shù)組產(chǎn)生任何影響。

如果此接口中的方法返回的注釋(直接或間接地)包含一個已賦值的 Class 成員脖母,該成員引用了一個在此 VM 中不可訪問的類士鸥,則試圖通過在返回的注釋上調(diào)用相關(guān)的類返回的方法來讀取該類,將導(dǎo)致一個 TypeNotPresentException谆级。

isAnnotationPresentbooleanisAnnotationPresent(Class annotationClass)

如果指定類型的注釋存在于此元素上烤礁,則返回 true,否則返回 false肥照。此方法主要是為了便于訪問標(biāo)記注釋而設(shè)計(jì)的脚仔。

參數(shù):

annotationClass - 對應(yīng)于注釋類型的 Class 對象

返回:

如果指定注釋類型的注釋存在于此對象上,則返回 true舆绎,否則返回 false

拋出:

NullPointerException - 如果給定的注釋類為 null

從以下版本開始:

1.5

getAnnotation TgetAnnotation(Class annotationClass)

如果存在該元素的指定類型的注釋玻侥,則返回這些注釋,否則返回 null亿蒸。

參數(shù):

annotationClass - 對應(yīng)于注釋類型的 Class 對象

返回:

如果該元素的指定注釋類型的注釋存在于此對象上凑兰,則返回這些注釋,否則返回 null

拋出:

NullPointerException - 如果給定的注釋類為 null

從以下版本開始:

1.5

getAnnotationsAnnotation[]getAnnotations()

返回此元素上存在的所有注釋边锁。(如果此元素沒有注釋姑食,則返回長度為零的數(shù)組。)該方法的調(diào)用者可以隨意修改返回的數(shù)組茅坛;這不會對其他調(diào)用者返回的數(shù)組產(chǎn)生任何影響音半。

返回:

此元素上存在的所有注釋

從以下版本開始:

1.5

getDeclaredAnnotationsAnnotation[]getDeclaredAnnotations()

返回直接存在于此元素上的所有注釋则拷。與此接口中的其他方法不同,該方法將忽略繼承的注釋曹鸠。(如果沒有注釋直接存在于此元素上煌茬,則返回長度為零的一個數(shù)組。)該方法的調(diào)用者可以隨意修改返回的數(shù)組彻桃;這不會對其他調(diào)用者返回的數(shù)組產(chǎn)生任何影響坛善。

返回:

直接存在于此元素上的所有注釋

從以下版本開始:

1.5

下面是使用反射讀取RUNTIME保留策略的Annotation信息的例子:

自定義注解:

@Retention(RetentionPolicy.RUNTIME)public@interfaceMyAnnotation {? ? String[] value1()default"abc";}

使用自定義注解:

publicclassAnnotationTest2 {@MyAnnotation(value1={"a","b"})@Deprecatedpublicvoidexecute(){? ? ? ? System.out.println("method");? ? }}

讀取注解中的信息:

publicstaticvoidmain(String[] args)throwsSecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {? ? AnnotationTest2 annotationTest2 =newAnnotationTest2();//獲取AnnotationTest2的Class實(shí)例Class c = AnnotationTest2.class;//獲取需要處理的方法Method實(shí)例Method method = c.getMethod("execute",newClass[]{});//判斷該方法是否包含MyAnnotation注解if(method.isAnnotationPresent(MyAnnotation.class)){//獲取該方法的MyAnnotation注解實(shí)例MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);//執(zhí)行該方法method.invoke(annotationTest2,newObject[]{});//獲取myAnnotationString[] value1 = myAnnotation.value1();? ? ? ? System.out.println(value1[0]);? ? }//獲取方法上的所有注解Annotation[] annotations = method.getAnnotations();for(Annotation annotation : annotations){? ? ? ? System.out.println(annotation);? ? }}

8、限定注解的使用:

限定注解使用@Target邻眷。

@Documented@Retention(value=RUNTIME)@Target(value=ANNOTATION_TYPE)public @interfaceTarget

指示注釋類型所適用的程序元素的種類眠屎。如果注釋類型聲明中不存在 Target 元注釋,則聲明的類型可以用在任一程序元素上肆饶。如果存在這樣的元注釋改衩,則編譯器強(qiáng)制實(shí)施指定的使用限制。 例如驯镊,此元注釋指示該聲明類型是其自身葫督,即元注釋類型。它只能用在注釋類型聲明上:

@Target(ElementType.ANNOTATION_TYPE)public@interfaceMetaAnnotationType {? ? ? ? ...? ? }

此元注釋指示該聲明類型只可作為復(fù)雜注釋類型聲明中的成員類型使用板惑。它不能直接用于注釋:

@Target({})public@interfaceMemberType {? ? ? ? ...? ? }

這是一個編譯時錯誤橄镜,它表明一個 ElementType 常量在 Target 注釋中出現(xiàn)了不只一次。例如洒放,以下元注釋是非法的:

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})public@interfaceBogus {? ? ? ? ...? ? }

public enumElementTypeextends Enum

程序元素類型蛉鹿。此枚舉類型的常量提供了 Java 程序中聲明的元素的簡單分類。

這些常量與 Target 元注釋類型一起使用往湿,以指定在什么情況下使用注釋類型是合法的妖异。

ANNOTATION_TYPE注釋類型聲明CONSTRUCTOR構(gòu)造方法聲明FIELD字段聲明(包括枚舉常量)LOCAL_VARIABLE局部變量聲明METHOD方法聲明PACKAGE包聲明PARAMETER參數(shù)聲明TYPE類、接口(包括注釋類型)或枚舉聲明

注解的使用限定的例子:

@Target(ElementType.METHOD)public@interfaceMyAnnotation {? ? String[] value1()default"abc";}

9领追、在幫助文檔中加入注解:

要想在制作JavaDoc文件的同時將注解信息加入到API文件中他膳,可以使用java.lang.annotation.Documented。

在自定義注解中聲明構(gòu)建注解文檔:

@Documentedpublic@interfaceMyAnnotation {? ? String[] value1()default"abc";}

使用自定義注解:

publicclassAnnotationTest2 {@MyAnnotation(value1={"a","b"})publicvoidexecute(){? ? ? ? System.out.println("method");? ? }}

10绒窑、在注解中使用繼承:

默認(rèn)情況下注解并不會被繼承到子類中棕孙,可以在自定義注解時加上java.lang.annotation.Inherited注解聲明使用繼承些膨。

@Documented@Retention(value=RUNTIME)@Target(value=ANNOTATION_TYPE)public @interfaceInherited

指示注釋類型被自動繼承蟀俊。如果在注釋類型聲明中存在 Inherited 元注釋,并且用戶在某一類聲明中查詢該注釋類型订雾,同時該類聲明中沒有此類型的注釋肢预,則將在該類的超類中自動查詢該注釋類型。此過程會重復(fù)進(jìn)行洼哎,直到找到此類型的注釋或到達(dá)了該類層次結(jié)構(gòu)的頂層 (Object) 為止烫映。如果沒有超類具有該類型的注釋沼本,則查詢將指示當(dāng)前類沒有這樣的注釋。

注意锭沟,如果使用注釋類型注釋類以外的任何事物抽兆,此元注釋類型都是無效的。還要注意族淮,此元注釋僅促成從超類繼承注釋辫红;對已實(shí)現(xiàn)接口的注釋無效。

上文摘自于:http://www.itzhai.com/java-based-notebook-annotation-annotation-introduction-and-use-custom-annotations.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瞧筛,一起剝皮案震驚了整個濱河市厉熟,隨后出現(xiàn)的幾起案子导盅,更是在濱河造成了極大的恐慌较幌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件白翻,死亡現(xiàn)場離奇詭異乍炉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)滤馍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門岛琼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人巢株,你說我怎么就攤上這事槐瑞。” “怎么了困檩?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵那槽,是天一觀的道長。 經(jīng)常有香客問我骚灸,道長糟趾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任甚牲,我火速辦了婚禮,結(jié)果婚禮上丈钙,老公的妹妹穿的比我還像新娘。我一直安慰自己著恩,他們只是感情好院尔,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布蜻展。 她就那樣靜靜地躺著,像睡著了一般纵顾。 火紅的嫁衣襯著肌膚如雪栋盹。 梳的紋絲不亂的頭發(fā)上施逾,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天汉额,我揣著相機(jī)與錄音,去河邊找鬼蠕搜。 笑死,一個胖子當(dāng)著我的面吹牛妓灌,可吹牛的內(nèi)容都是我干的蜜宪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼掉伏,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了斧散?” 一聲冷哼從身側(cè)響起照捡,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎栗精,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鹿寨,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡薪夕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年脚草,在試婚紗的時候發(fā)現(xiàn)自己被綠了原献。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片埂淮。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡写隶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出慕趴,到底是詐尸還是另有隱情,我是刑警寧澤冕房,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布耙册,位于F島的核電站,受9級特大地震影響觅玻,放射性物質(zhì)發(fā)生泄漏培漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一畸悬、第九天 我趴在偏房一處隱蔽的房頂上張望珊佣。 院中可真熱鬧蹋宦,春花似錦咒锻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至恭取,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耗跛,已是汗流浹背裕照。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工牍氛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留烟阐,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓蜒茄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親玩祟。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

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

  • java自定義注解 Java注解是附加在代碼中的一些元信息,用于一些工具在編譯润讥、運(yùn)行時進(jìn)行解析和使用,起到說明楚殿、配...
    尼爾君閱讀 518評論 0 0
  • 從JDK5開始脆粥,Java增加了Annotation(注解)砌溺,Annotation是代碼里的特殊標(biāo)記变隔,這些標(biāo)記可以在...
    CarlosLynn閱讀 561評論 0 2
  • 同時發(fā)布于 知乎 Java 注解 1.注解的由來 在引入注解之前匣缘,在不同類型的應(yīng)用程序使用XML作為標(biāo)準(zhǔn)的代碼配置...
    踐行者閱讀 978評論 0 0
  • 注解 創(chuàng)建注解 下面代碼創(chuàng)建了一個名為MyAnno的注解,有兩個成員str和val孵户。@Retention(…)注解...
    kylinxiang閱讀 3,631評論 0 2
  • 20 17,10.29 星期天 晴 今天的天氣特別好,我的心情也很好检柬。因?yàn)榻裉焓堑氖莻€特殊的日子。女兒中...
    芳香四季閱讀 191評論 0 1