詳解Java注解( Annotation )

詳解Java注解( Annotation )

注解的定義:

注解(Annotation),也叫元數(shù)據(jù)。一種代碼級(jí)別的說明。它是JDK1.5及以后版本引入的一個(gè)特性,與類、接口、枚舉是在同一個(gè)層次。它可以聲明在包、類、字段、方法、局部變量、方法參數(shù)等的前面,用來對(duì)這些元素進(jìn)行說明,注釋

注解的作用

  • 生成文檔

  • 代碼分析,通過代碼里的元數(shù)據(jù)來對(duì)代碼進(jìn)行分析

  • 在編譯的時(shí)候進(jìn)行檢查

JDK自帶的注解

在開發(fā)過程中,我們見到的JDK自帶的注解主要有三個(gè),分別是@Override@SuppressWarnings@Deprecated,作用分別如下:

  • @Override

  • 主要用于標(biāo)識(shí)所用的方法是繼承自父類的方法,從而在編譯的過程中可以被編譯器檢測(cè)到,如果某個(gè)方法使用了該注解,但是方法的簽名(方法名以及參數(shù)類型)與父類不一致,則在編譯的過程中,編譯器會(huì)拋出錯(cuò)誤,用于提示開發(fā)者。

  • 最常見的就是toString()方法了,該方法繼承自O(shè)bject類。如果我們?cè)谥貙懺摲椒ǖ臅r(shí)候,沒有使用該注解,然后不小心將該方法的名字寫錯(cuò)如下所示:


package cn.xuhuanfeng.annotation;

public class TestAnnotation {

public static void main(String[] args) {

TestAnnotation test = new TestAnnotation();

System.out.println(test.toString());

}

public String tostring() {

return "Not true";

}

}

輸出結(jié)果為:cn.xuhuanfeng.annotation.TestAnnotation@15db9742,顯然我們可以看到,toString()方法輸出的結(jié)果顯然不是我們所期待的,有時(shí)候就會(huì)很莫名其妙了(原因是重寫toString() 方法的時(shí)候,不小心將S寫錯(cuò)成了s,編譯器會(huì)理解成有一個(gè)新的方法,叫tostring(),這是正確的,所以就導(dǎo)致了調(diào)用的時(shí)候出現(xiàn)了預(yù)期之外的結(jié)果了),但是如果我們?cè)谥貙?code>toString()方法的時(shí)候,加上@Override,這個(gè)時(shí)候,如果還是按照上面的寫法,編譯器就會(huì)告訴我們The method tostring() of type TestAnnotation must override or implement a supertype method,于是,我們很容易就能發(fā)現(xiàn)問題所在了,這是注解的好處之一,也是@Override 的作用,具體可以查看其源碼即可。

  • @Deprecated

  • 主要用于標(biāo)識(shí)該包、方法、域、變量等已經(jīng)不推薦使用了,一旦標(biāo)識(shí)了該注解,則對(duì)應(yīng)的方法、域等會(huì)劃上刪除線如下所示


@Deprecated

public void test(){

System.out.println("Deprecated");

}

  • @SuppressWarnings

  • 主要用于壓制編譯器發(fā)出的警告,該注解需要提供參數(shù),包括了unchecked all 等,分別對(duì)應(yīng)不同的壓制范圍,如:


@SuppressWarnings("all")

public void test01(){

}

自定義注解

上面我們看到了JDK中自帶的注解,雖然很有用,但是畢竟范圍有限,種類也有限,實(shí)用性不是很大,于是Java開發(fā)者為我們提供了自定義的注解,極大了擴(kuò)展了該功能,下面我們就詳細(xì)來看下自定義注解的內(nèi)容。

元注解

為了使用自定義注解,首先我們需要了解一個(gè)概念:元注解,所謂的元注解,其實(shí)就是注解的注解,也就是用來表示注解的注解,JDK中包含的元注解中比較常用的有以下幾種類型: @Target , @Retention , @Documented , @Inherited ,其中前面兩種在實(shí)際開發(fā)過程中用得比較多,所以下面我們著重來介紹這兩種:

  • @Target :

  • 用于表示所標(biāo)識(shí)的注解的使用范圍,其值可以是 ElementType.PACKAGE , ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD 等,分別對(duì)應(yīng)的標(biāo)識(shí)對(duì)象為 包,構(gòu)造器,方法,域變量,也就是說,只有包含了該范圍,我們定義出來的注解才能用于對(duì)應(yīng)的域,多種類型可以組合使用,只需要使用{}包括起即可。

  • 具體使用如下:

@Target({ElementType.PACKAGE,ElementType.CONSTRUCTOR ,ElementType.METHOD, ElementType.FIELD})

  • @Retention

  • 用于標(biāo)識(shí)注解的存活周期,包括了RetentionPolicy.RUNTIME,RetentionPolicy.CLASS,RetentionPolicy.SOURCE,分別對(duì)應(yīng)存活周期為運(yùn)行時(shí),字節(jié)碼,源文件。

  • 運(yùn)行時(shí):標(biāo)識(shí)該注解存在于字節(jié)碼中,并且在運(yùn)行過程中會(huì)被JVM加載,可用于反射操作。

  • 字節(jié)碼:標(biāo)識(shí)該注解存在于字節(jié)碼中,但是運(yùn)行時(shí)不被JVM加載,默認(rèn)的形式。

  • 源文件:標(biāo)識(shí)該注解只存在源文件中,在編譯過程會(huì)被編譯器丟棄。

  • 具體使用如下:


@Retention(RetentionPolicy.RUNTIME)

自定義注解

學(xué)習(xí)完了元注解之后,我們就可以開始手動(dòng)編寫自定義的注解了。

  • 格式:

自定義注解的書寫方式跟普通的Java類的書寫方式接近,只是將class 關(guān)鍵字替換為@interface ,如下:


@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.PACKAGE})

public @interface MyAnnotation {

}

從上面的元注解部分我們可以知道,我們定義的注解MyAnnotation 只能用于注解包,而不能用于注解方法、域等。

  • 參數(shù):

從前面的@SuppressWarnings 中我們可以知道,注解還可以帶參數(shù),不過在注解中的參數(shù)類型有點(diǎn)奇怪,如下:


String value();// String為參數(shù)類型 value() 整體為變量

String[] value(); // String[] 為參數(shù)類型 value() 整體為變量

默認(rèn)情況下,如果只有一個(gè)參數(shù)類型,我們將變量命名為value(),我們也可以聲明多個(gè)參數(shù)


String name();

int age(); // 其他類型依此類推

在注解中的所有參數(shù)均可以指定默認(rèn)的值,如下:


String name() default "";

int age() default -1;

由于在使用注解中我們無法標(biāo)識(shí)錯(cuò)誤的情況,所以一般情況下,會(huì)將默認(rèn)類型指定為一個(gè)不合理值,用來處理注解時(shí)判斷所使用的值是合理還是不合理。

  • 使用:

定義完了一個(gè)我們的自定義注解之后,接下來我們來看下如何使用它。使用的方式跟JDK自帶的注解的方式基本一致,指定對(duì)應(yīng)的鍵值對(duì),key為定義的參數(shù)名字,值為需要傳入的值,如果是數(shù)組類型,則傳入數(shù)組即可。


@MyAnnotation(name="xuhaunfeng",age=23)

public void test(){}

//在MyAnnotation中多增加一個(gè)變量為 String[] parents();

@MyAnnotation(name="xuhaunfeng",age=23,parents={"AA","BB"})

public void test(){}

注解的應(yīng)用

看完了上面的內(nèi)容,可能你會(huì)覺得如果注解只是上面的用法,感覺上是沒有任何作用的,確實(shí),上面所介紹的內(nèi)容都是注解的格式、定義等,但是沒有涉及到其應(yīng)用,注解配合反射,可以實(shí)現(xiàn)很多功能,例如:ORM的實(shí)現(xiàn),框架中Annotation的應(yīng)用等,不過目前我還沒有學(xué)習(xí)到這些內(nèi)容,所以在后期學(xué)習(xí)之后將會(huì)補(bǔ)上,敬請(qǐng)期待。

參考說明

這篇文章只是我個(gè)人學(xué)習(xí)過程中的一些筆記,不帶有任何的商業(yè)目的,在學(xué)習(xí)過程中參考了很多的資料,主要參考深入理解Java:注解(Annotation)自定義注解入門 By竹子,在此對(duì)竹子表示感謝。如果本文涉及的一些內(nèi)容有一些版權(quán)爭(zhēng)議,還請(qǐng)與我聯(lián)系。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評(píng)論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,497評(píng)論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評(píng)論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評(píng)論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,727評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,193評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,411評(píng)論 0 288
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,945評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,777評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,978評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,216評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評(píng)論 1 286
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,657評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,960評(píng)論 2 373

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