由淺入深 帶你了解 JAVA 注解

在學(xué)習(xí)注解之前敞峭,我首先來講一講學(xué)習(xí)注解的好處殖蚕,不管下面看不看,先打個雞血先宛官。不過確定的是刻坊,在正常 JAVA 開發(fā)中,自己寫注解是比較少的胡控,更多的情況就是使用第三方庫的注解橙困,正因為如此肠缔,大多數(shù)開發(fā)者對于注解僅僅停留在會用的地步槽华。試想一下懂鸵,當(dāng)大多數(shù)人都不會的時候你會,那么你是不是就超越的大部分人夺巩。除此之外续镇,我還總結(jié)學(xué)習(xí)注解的3大好處:

  1. 能夠讀懂別人寫的代碼,特別是框架相關(guān)的代碼;
  2. 讓編程更加簡潔,代碼更加清晰;
  3. 讓別人高看一眼挟阻,裝逼利器;

說完了這些,下面就開始真干貨了俯在。

注解概念

JDK 5中引入了源代碼中的注解(annotation)這一機制愕提。 注解使得Java源代碼中不但可以包含功能性的實現(xiàn)代碼如输,還可以添加元數(shù)據(jù)订歪。 注解的功能類似于代碼中的注釋虑润,所不同的是注解不是提供代碼功能的說明过牙,而是實現(xiàn)程序功能的重要組成部分谦秧。

Java中常見注解

對于常見注解集歇,單單看在開發(fā) JAVA 時 IDE 彈出的那些注解就能了解到焕窝,對于JDK 的注解,我們是要非常熟悉才行。

JDK自帶注解

  • @Override
  • @Deprecated
  • @Suppvisewarnings

常見第三方注解

  • Spring

    • @Autowired
    • @Service
    • @Repository
  • Mybatis

    • @InsertProvider
    • @UpdateProvider
    • @Options

注解的分類

按照運行機制分類

  • 源碼注解 (注解只在源碼中存在,編譯成.class文件就不存在了)
  • 編譯時注解 (注解在源碼和.class文件中都存在)
  • 運行時注解 (在運行階段還起作用夹纫,甚至?xí)绊戇\行邏輯的注解,例如 @Autowired

按照來源分類

  • 來自JDK的注解
  • 來自第三方的注解
  • 自定義注解

元注解

給注解使用的注解

自定義注解

下面是一個典型的注解聲明院刁,大家先看個大概困鸥,下面會對定義注解的注意事項做個說明:

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {
    String desc();
    String author();
    int age() default 18;
}

  1. 使用@interface關(guān)鍵字定義注解
  2. 成員(變量)以無參數(shù)無異常方式聲明
  3. 可以用default為成員指定一個默認值
  4. 注解中成員的類型是受限制的姑荷,合法的類型包括基本數(shù)據(jù)類型以及 StringClass寨闹、 AnnotationEnumeration
  5. 如果注解只有一個成員净赴,則成員名應(yīng)該為value(),在使用時可以忽略成員名和賦值號(=
  6. 注解類可以沒有成員魔吐,沒有成員的注解稱為標(biāo)識注解
  7. 元注解浮定,用于對注解進行的注解,例如Description注解上面的4個注解

常用元注解

Target

標(biāo)識注解的作用域嘿棘,作用域有以下幾種坪郭,幾乎包含了 JAVA 所有的類型:

  1. ElementType.CONSTRUCTOR:構(gòu)造方法
  2. ElementType.FIELD:字段
  3. ElementType.LOCAL_VARIABLE:局部變量
  4. ElementType.METHOD:方法
  5. ElementType.PACKAGE:包
  6. ElementType.PARAMETER: 參數(shù)
  7. ElementType.TYPE:類、接口

例如上面例子中標(biāo)識了Description可以用于對方法和類或接口進行注解:

@Target({ElementType.PARAMETER, ElementType.TYPE})

Retention

標(biāo)識注解的生命周期,有以下3種值:

  1. RetentionPolicy.SOURCE:只在源碼顯示碳默,編譯時會丟棄
  2. RetentionPolicy.CLASS:編譯時會記錄到class文件中,運行時會忽略
  3. RetentionPolicy.RUNTIME:運行時存在,可以通過反射讀取

例如上面的例子中標(biāo)識了Description可以記錄到class文件中,但在運行時會忽略:

@Retention(RetentionPolicy.CLASS)

Inherited

標(biāo)識性元注解芝此,標(biāo)識該注解允許子類進行繼承租副。注意這里可不是注解的繼承秸抚,注解之間也沒有繼承什么的鹿驼。這里指的是如果一個類(不是接口)聲明上使用了這個注解,那么當(dāng)它的一個子類繼承該類時辕宏,也會擁有與父類一樣擁有該注解畜晰。

Documented

標(biāo)識在生成 JAVA DOC 時會包含該注解

使用自定義注解

使用注解的語法:

@<注解名>(<成員名1>=<成員值1>, <成員名1>=<成員值1>, <成員名1>=<成員值1>, ...)

其中的成員名則對應(yīng)了注解里的成員,例子:

@Description(desc="description", author="swifter", age=18)
public String getColor() {
    return "red";
}

上面只是個簡單的例子匾效,下面給出一個注解的詳細使用方式舷蟀,這也是在正常開發(fā)中會使用到的方式。對于注解面哼,上面的代碼中已經(jīng)給出了一個聲明野宜,下面就寫兩個類來使用該注解。通過這兩個例子魔策,怎么使用注解就顯而易見了匈子。

第一個類 Person

@Description(desc="person interface", author="swifter")
public abstract class Person {
    @Description(desc="method getName", author="swifter")
    abstract String getName();
    abstract void doSomething();
}

第二個類 Child 繼承自 Person

public class Child extends Person {

    @Override
    @Description(desc="child method getName", author="swifter")
    public String getName() {
        return "get child";
    }

    @Override
    public void doSomething() {
        System.out.println("do something in child class");
    }
}

解析注解

既然已經(jīng)定義了注解,那么就應(yīng)該考慮如何在代碼中解析這個注解了闯袒。解析注解就是通過反射獲取類虎敦、函數(shù)或成員上的運行時注解信息,從而實現(xiàn)動態(tài)控制程序運行的邏輯政敢。
解析主要方式就是通過反射的途徑其徙,通過Class對象來獲取注解,并拿到注解的字段再進行操作喷户。例如下面的例子:

Class<Child> clazz = Child.class;

if(clazz.isAnnotationPresent(Description.class)) {
    Description description = clazz.getAnnotation(Description.class);
    System.out.println(description.desc()+" : "+description.author());
}

Method[] methods = clazz.getMethods();
for(Method method : methods) {
    if(method.isAnnotationPresent(Description.class)) {
        Description description = method.getAnnotation(Description.class);
        System.out.println(description.desc()+" : "+description.author());
    }
}

運行之后客戶端會給出如下結(jié)果:

person interface : swifter
child method getName : swifter

其中第一行顯示的是類上面的注解信息唾那,第二行則顯示的是方法上的注解信息。對于這兩個注解的對象褪尝,在代碼中可以看到闹获,都是通過反射的形式拿到的期犬。雖然說反射的方式在效率上比較慢,但是想想注解帶來的優(yōu)點避诽,掌握注解還是有很大必要的龟虎。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市沙庐,隨后出現(xiàn)的幾起案子鲤妥,更是在濱河造成了極大的恐慌,老刑警劉巖轨功,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旭斥,死亡現(xiàn)場離奇詭異容达,居然都是意外死亡古涧,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門花盐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羡滑,“玉大人,你說我怎么就攤上這事算芯∑饣瑁” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵熙揍,是天一觀的道長职祷。 經(jīng)常有香客問我,道長届囚,這世上最難降的妖魔是什么有梆? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮意系,結(jié)果婚禮上泥耀,老公的妹妹穿的比我還像新娘。我一直安慰自己蛔添,他們只是感情好痰催,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著迎瞧,像睡著了一般夸溶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凶硅,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天缝裁,我揣著相機與錄音,去河邊找鬼咏尝。 笑死压语,一個胖子當(dāng)著我的面吹牛啸罢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胎食,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼扰才,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了厕怜?” 一聲冷哼從身側(cè)響起衩匣,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎粥航,沒想到半個月后琅捏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡递雀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年柄延,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缀程。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡搜吧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出杨凑,到底是詐尸還是另有隱情滤奈,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布撩满,位于F島的核電站蜒程,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏伺帘。R本人自食惡果不足惜昭躺,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望曼追。 院中可真熱鬧窍仰,春花似錦、人聲如沸礼殊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晶伦。三九已至碟狞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間婚陪,已是汗流浹背族沃。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脆淹。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓常空,卻偏偏與公主長得像,于是被迫代替她去往敵國和親盖溺。 傳聞我的和親對象是個殘疾皇子漓糙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

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

  • 什么是注解(Annotation):Annotation(注解)就是Java提供了一種元程序中的元素關(guān)聯(lián)任何信息和...
    九尾喵的薛定諤閱讀 3,174評論 0 2
  • 本文章涉及代碼已放到github上annotation-study 1.Annotation為何而來 What:A...
    zlcook閱讀 29,178評論 15 116
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)烘嘱,斷路器昆禽,智...
    卡卡羅2017閱讀 134,693評論 18 139
  • 日記的最近更新日期停在6月25號醉鳖,已經(jīng)一個多月沒寫日記了。于是哮内,長時間的積累盗棵,給了自己一個下筆的借口。 6月25牍蜂,...
    遙途閱讀 410評論 1 3
  • 多樣化的現(xiàn)代生活帶給我們很多新鮮感的同時鲫竞,也使很多人得了效應(yīng)并發(fā)癥----孤獨癥。 豐富光鮮的朋友圈背后更體現(xiàn)了一...
    阿菜Choi閱讀 474評論 1 1