Retrofit學(xué)習(xí)(二)

概述

上一篇已經(jīng)記載了關(guān)于Retrofit使用的相關(guān)知識(shí)卢厂,這一片主要記錄下Retrofit實(shí)現(xiàn)的相關(guān)原理沟沙。簡(jiǎn)要來說河劝,主要是運(yùn)用了注解,動(dòng)態(tài)代理等技術(shù)矛紫,這一篇先講下注解赎瞎。


注解

什么是注解

首先來了解下注解是什么。
注解是自Java1.5版本引入的颊咬;同時(shí)引入的還有反射务甥,注解的實(shí)現(xiàn)必須依賴反射,但是反射并不依賴注解喳篇。
注解是一種應(yīng)用于類敞临、方法、參數(shù)杭隙、變量哟绊、構(gòu)造器及包聲明中的特殊修飾字符。他是一種由JSR-175標(biāo)準(zhǔn)選擇用來描述元數(shù)據(jù)的一種工具痰憎。
舉個(gè)栗子:

@Override
public String toString() {
    return "This is to String";
}

@Override告訴編譯器這個(gè)方法是重寫的父類的方法票髓,如果父類中不存在這個(gè)方法,那么編譯器就會(huì)報(bào)錯(cuò)铣耘,提示父類中沒有這個(gè)方法洽沟。但是如果toString寫成了toStrring,那么沒有使用@Override也是沒有問題的蜗细。但是運(yùn)行的結(jié)果就跟toString沒有什么關(guān)系了裆操。

為什么要引入注解

注解的常見作用有一下幾種:

  • 生成文檔。 這是最常見的炉媒,也是java最早提供的注解踪区。比如:@see @param @return等等
  • 跟蹤代碼依賴性,實(shí)現(xiàn)替代配置文件功能吊骤。這個(gè)就類似Retrofit中的注解的功能缎岗。
  • 在編譯的時(shí)候進(jìn)行格式檢查。比如:@Override放在方法前白粉,如果你這個(gè)方法并不是覆蓋超類的方法就能檢查出來传泊。

原理

注解從本質(zhì)上來說其實(shí)是一種接口。注解本身是不會(huì)影響程序代碼的執(zhí)行鸭巴,無論注解怎么變化眷细,代碼都是一樣的執(zhí)行。Java語(yǔ)言解釋器在工作的時(shí)候會(huì)忽略這些注解鹃祖,因此在JVM中這些注解是“不起作用的”溪椎。但是Java可以通過反射的機(jī)制來訪問注解信息。相關(guān)的類根據(jù)注解中的信息再?zèng)Q定如何改變程序的元素或者改變他們的行為。
注解與接口又存在一些區(qū)別:

  • 注解類型使用的關(guān)鍵字是@interface而不是interface池磁。(這個(gè)關(guān)鍵字聲明隱含了一個(gè)信息:他是繼承java.lang.annotation.Annotation接口奔害,而不是聲明了一個(gè)interface 楷兽。)
  • 注解類型地熄、方法定義是獨(dú)特的、受限制的芯杀。(注解里沒有直接定義成員名端考,方法名就是表示注解在使用時(shí)用到的成員名,而方法的返回值表示成員名的類型)

注解與接口相似的地方:他們都可以定義常量揭厚,靜態(tài)成員類型却特。注解類型也可以像接口一樣被實(shí)現(xiàn)或者繼承。


自定義Annotation

在介紹如何自定義注解之前筛圆,先來了解下元注解裂明,這些元注解在自定義注解過程中用得到
元注解
java.lang.annotation提供了四種元注解,專門用來注解其他的注解太援。

  • @Documented:一個(gè)簡(jiǎn)單的Annotations標(biāo)記注解闽晦,表示是否將注解信息添加在java文檔中。
  • @Retention:表示在什么級(jí)別保存該注解信息提岔。
  • @Target:表示注解用在什么地方仙蛉。
  • @Inherited:表示允許子類繼承父類中的注解。

Retention定義了注解的生命周期碱蒙,有以下幾個(gè)枚舉選項(xiàng):

  • RetentionPolicy.SOURCE:在編譯階段丟棄荠瘪。這些注解在編譯結(jié)束之后就不再有任何意義,所以他們不會(huì)寫入字節(jié)碼赛惩。 @Override哀墓,@SuppressWarnings都屬于這類注解。
  • RetentionPolicy.CLASS:在類加載階段丟棄喷兼。在字節(jié)碼文件的處理中有用篮绰。注解默認(rèn)使用這種方式。
  • RetentionPolicy.RUNTIME:始終不會(huì)丟棄褒搔,運(yùn)行時(shí)期也是保留該注解阶牍,因此可以使用反射機(jī)制來讀取該注解的信息。這也是我們自定義注解常用的方式星瘾。

Target 表示注解用在什么地方走孽。如果沒明確指出,默認(rèn)是可以放在任何地方的琳状。以下是一些可用的參數(shù)磕瓷。需要說明的是:屬性的注解是兼容的,如果你想給7個(gè)屬性都能添加注解,僅僅排除一個(gè)屬性困食,那么你需要在定義target包含的所有屬性边翁。

  • ElementType.TYPE: 用于描述類。接口或enum聲明
  • ElementType.FIELD:用于描述實(shí)例變量
  • ElementType.METHOD:用于描述方法
  • ElementType.PARAMETER:用于描述參數(shù)
  • ElementType.CONSTRUCTOR:用于描述構(gòu)造函數(shù)
  • ElementType.LOCAL_VARIABLE:用于描述局部變量
  • ElementType.ANNOTATION_TYPE 用于注解另一個(gè)注解
  • ElementType.PACKAGE 用于記錄java文件的package信息

Inherited 定義該注釋和子類的關(guān)系硕盹。

自定義注解
首先定義兩個(gè)自定義的注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassAnnotation {
   String value() default "這是一個(gè)類的注解";
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodAnnotation {
    String value() default "這是一個(gè)方法的注解";
    String name();
}

定義一個(gè)運(yùn)用注解的普通類:

@ClassAnnotation
public class AnnotationUser {
    
    @MethodAnnotation(name="test method")
    public void testMethod(){
        System.out.println("測(cè)試方法");
    };
}

解釋注解:

Class iAnnotationUser = Class.forName("com.test.retrofit.annotation.AnnotationUser");
            Method[] methods = iAnnotationUser.getMethods();
            boolean isAP = iAnnotationUser.isAnnotationPresent(ClassAnnotation.class);
            if(isAP){
                ClassAnnotation classAnnotation = (ClassAnnotation)(iAnnotationUser.getAnnotation(ClassAnnotation.class));
                System.out.println("類注解信息:"+classAnnotation.value());
            }
            
            for(Method m:methods){
                if(m.isAnnotationPresent(MethodAnnotation.class)){
                    MethodAnnotation ma = m.getAnnotation(MethodAnnotation.class);
                    System.out.println("方法注解:"+ma.value()+" 給注解成員賦值:"+ma.name());
                    m.invoke(new AnnotationUser(), null);
                }
            }

運(yùn)行結(jié)果:

類注解信息:這是一個(gè)類的注解
方法注解:這是一個(gè)方法的注解 給注解成員賦值:test method
測(cè)試方法

以上就是注解的相關(guān)基本知識(shí)和運(yùn)用符匾。
另外關(guān)于注解的實(shí)現(xiàn),知乎上有個(gè)問答解釋得較好: http://www.zhihu.com/question/24401191

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瘩例,一起剝皮案震驚了整個(gè)濱河市啊胶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垛贤,老刑警劉巖焰坪,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異聘惦,居然都是意外死亡某饰,警方通過查閱死者的電腦和手機(jī)能庆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門浦马,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笛园,你說我怎么就攤上這事涂邀∥练拢” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵比勉,是天一觀的道長(zhǎng)劳较。 經(jīng)常有香客問我,道長(zhǎng)浩聋,這世上最難降的妖魔是什么观蜗? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮衣洁,結(jié)果婚禮上墓捻,老公的妹妹穿的比我還像新娘。我一直安慰自己坊夫,他們只是感情好砖第,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著环凿,像睡著了一般梧兼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上智听,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天羽杰,我揣著相機(jī)與錄音渡紫,去河邊找鬼。 笑死考赛,一個(gè)胖子當(dāng)著我的面吹牛惕澎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播颜骤,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼唧喉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了复哆?” 一聲冷哼從身側(cè)響起欣喧,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎梯找,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體益涧,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锈锤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了闲询。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片久免。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖扭弧,靈堂內(nèi)的尸體忽然破棺而出阎姥,到底是詐尸還是另有隱情,我是刑警寧澤鸽捻,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布呼巴,位于F島的核電站,受9級(jí)特大地震影響御蒲,放射性物質(zhì)發(fā)生泄漏衣赶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一厚满、第九天 我趴在偏房一處隱蔽的房頂上張望府瞄。 院中可真熱鬧,春花似錦碘箍、人聲如沸遵馆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)货邓。三九已至,卻和暖如春多艇,著一層夾襖步出監(jiān)牢的瞬間逻恐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留复隆,地道東北人拨匆。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像挽拂,于是被迫代替她去往敵國(guó)和親惭每。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

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