首先。寫(xiě)這篇文章是因?yàn)榫W(wǎng)上大部分對(duì)這兩個(gè)技術(shù)通常都分開(kāi)描述藏否,似乎沒(méi)有一篇文章對(duì)兩者之間專(zhuān)門(mén)描述期吓,所以才有了這篇文章苛白。該文章適合對(duì)注解與反射不了解或者不知道這兩個(gè)如何搭配的人看呐赡。如果你有一定了解可以選擇性查看退客。
文章會(huì)分三部分:反射與注解的基本使用與搭配,并盡可能的簡(jiǎn)短(我不太適合長(zhǎng)篇大論链嘀,并且如果兩個(gè)技術(shù)點(diǎn)一起講估計(jì)會(huì)很長(zhǎng)萌狂,這篇可是當(dāng)作是“指導(dǎo)篇”吧)會(huì)有幾個(gè)鏈接方便讀者查看更詳細(xì)內(nèi)容。
注解在Android中應(yīng)用的范圍還是比較廣的怀泊,流行庫(kù)Retrofit Butterknife等都使用到了注解的技術(shù)茫藏,?我們經(jīng)常使用但它的具體操作是怎么一個(gè)流程呢?當(dāng)你第一次使用快捷鍵想看這個(gè)注解里面都做的了什么的時(shí)候你會(huì)看到比如類(lèi)似這樣
第一感覺(jué)就是懵逼(我cao這怎么什么都沒(méi)有注解這到底是干嘛的)這時(shí)候估計(jì)你就點(diǎn)回來(lái)繼續(xù)擼別的代碼了包个。嗯刷允。我之前也是這樣冤留。好碧囊。要想知道它是用來(lái)干什么先來(lái)看看反射。
反射
簡(jiǎn)單來(lái)說(shuō)纤怒,反射就是在運(yùn)行時(shí)可以獲取任意 Class 或 Object 內(nèi)部所有成員屬性糯而,如成員變量、成員方法泊窘、構(gòu)造函數(shù)和 Annotation(注解)
推薦大家先看這位大神的文章了解一下,對(duì)反射的基本使用講解的還是很清楚的
http://wingjay.com/2017/04/26/Java-%E6%8A%80%E6%9C%AF%E4%B9%8B%E5%8F%8D%E5%B0%84/
我們可以通過(guò)getDeclaredFields getDeclaredMethods getDeclaredConstructors
等方法獲取常用的成員變量熄驼、獲取成員方法像寒、獲取構(gòu)造函數(shù)等等
而其中我們可以通過(guò)isAnnotationPresent getAnnotation
來(lái)判斷某個(gè)方法或變量甚至類(lèi)是否被某個(gè)注解類(lèi)注解,并且獲取注解類(lèi)中的變量與被注解的變量或方法的參數(shù)等等瓜贾。
舉個(gè)栗子:
這里可以看到通過(guò)反射拿到了注解類(lèi)中輸入的參數(shù)然后對(duì)其變量進(jìn)行操作诺祸。到這里大概就應(yīng)該有點(diǎn)明白了吧。下來(lái)我們就說(shuō)說(shuō)注解祭芦。
注解
注解就相當(dāng)于一個(gè)模板筷笨,通過(guò)注解的方式直接套用在不同的地方。省去了很多utils等多余的代碼龟劲。同樣可以使用注解來(lái)自動(dòng)生成代碼了胃夏,注解作用很強(qiáng)大。
注解的基本知識(shí)依然推薦大家先看這位大神的文章了解一下昌跌,對(duì)注解有個(gè)概念
http://wingjay.com/2017/05/03/Java-%E6%8A%80%E6%9C%AF%E4%B9%8B%E6%B3%A8%E8%A7%A3-Annotation/
自定義注解時(shí)我們可以通過(guò)RetentionPolicy.SOURCE RetentionPolicy.CLASS RetentionPolicy.RUNTIME
規(guī)定注解在編輯期編譯期仰禀、運(yùn)行期它是否進(jìn)行參與
使用@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
來(lái)指定可以被注解的對(duì)象,更多用法可以看上面的鏈接這里就不細(xì)講了蚕愤。
他的寫(xiě)法是通常如第一張圖(BindView)答恶,使用時(shí)像這樣
是不是感覺(jué)很熟悉。是不是和Butterknife如出一轍萍诱。好亥宿。下面就該說(shuō)說(shuō)反射和注解的搭配了。
搭配
如果你仔細(xì)看了前面的內(nèi)容包括這兩個(gè)鏈接那么下面的東西你應(yīng)該很好吸收了砂沛,如果沒(méi)有仔細(xì)看還是先回頭看看烫扼,否則可能會(huì)不理解
以上面BindView為例,通過(guò)圖解來(lái)講講它們結(jié)合在一起的使用:
- 首先我們需要一個(gè)BindView注解類(lèi)作為模板來(lái)收集數(shù)據(jù)碍庵,指定它被用于成員變量并且在運(yùn)行時(shí)出依然有效映企,同時(shí)需要一個(gè)value來(lái)作為后面
findviewById
的值
- 這時(shí)你就可以使用注解了,并調(diào)用方法將activity傳入便于后續(xù)操作静浴,這里我沒(méi)有直接使用
setContentView
方法堰氓,我同樣使用了注解方式,設(shè)置布局方法類(lèi)似你看完肯定也就會(huì)寫(xiě)了苹享,這個(gè)就留給讀者了双絮。
- 模板寫(xiě)好了也用在了具體的地方,這時(shí)我們就該編寫(xiě)反射類(lèi)來(lái)獲取注解里輸入的值與變量得问。?并進(jìn)行對(duì)應(yīng)操作
上面的代碼通過(guò)對(duì)反射拿出所有被BindView注解的成員變量并取出BindView的value值進(jìn)行findviewById
給成員變量賦值囤攀。就這么幾行代碼就完成了一個(gè)簡(jiǎn)單的Butterknife對(duì)View進(jìn)行賦值的一個(gè)操作。
注解和反射是一扇新大門(mén)宫纬。對(duì)注解和注解和反射有很好的操作話(huà)會(huì)節(jié)省很多我們重復(fù)的工作焚挠。甚至少寫(xiě)很多代碼就能完成同樣的事情。
總結(jié):注解就是模板漓骚,收集需要的數(shù)據(jù)和可以看做是一種特殊的函數(shù)蝌衔,使用反射拿到注解和被注解的值進(jìn)行操作榛泛。
希望本篇文章對(duì)初始注解和反射的人會(huì)有幫助。