Android中反射的簡單應(yīng)用

自己對反射的理解和應(yīng)用還處于比較淺顯的階段,寫這篇文章更多在于整理總結(jié)姥卢,也就是幫助自己進(jìn)一步的理解和學(xué)習(xí)反射機(jī)制摔蓝。

反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以訪問盏触、檢測和修改它本身狀態(tài)或行為的一種能力渗蟹。

java中類反射

反射是 Java 程序開發(fā)語言的特征之一块饺,它允許運(yùn)行中的 Java 程序?qū)?strong>自身進(jìn)行檢查,或者說“自審”拙徽,并能直接操作程序的內(nèi)部屬性和方法刨沦。
簡單總結(jié)這些定義,那就是反射可以讓我們獲得一個(gè)類的所有信息膘怕,包括私有屬性和私有方法想诅,對于我們這種小白,先知道這點(diǎn)就可以啦岛心,那在java中如何使用發(fā)射呢来破。這里我們隨便創(chuàng)建一個(gè)類來演示。比如說創(chuàng)建一個(gè)Book類:

public class Book implements Parcelable
{
    private int id=1;
    private String name="android";

    private String author="wf";

    private String getName()
    {
        return name;
    }
}

Book類中屬性和方法都是私有的忘古,現(xiàn)在我們通過反射來訪問這些屬性和方法徘禁。

String s = null;
try
{
    Class<?> bookClass = Class.forName("cc.abto.demo.Book");//完整類名
    Object book = bookClass.newInstance();//獲得實(shí)例
    Method getAuthor = bookClass.getDeclaredMethod("getName");//獲得私有方法
    getAuthor.setAccessible(true);//調(diào)用方法前,設(shè)置訪問標(biāo)志
    s = (String) getAuthor.invoke(book);//使用方法
}
catch (Exception e)
{
    e.printStackTrace();
}

可以看到上面代碼中我們用Class和Method這兩個(gè)類完成了反射髓堪,這兩個(gè)類分別對應(yīng)了類和方法送朱,也就是包裝了類和方法的信息,下面對反射的部分API做一下簡單介紹:

  • Class類:代表一個(gè)類干旁,位于java.lang包下
  • Field類:代表類的成員變量(成員變量也稱為類的屬性)
  • Method類:代表類的方法
  • Constructor類:代表類的構(gòu)造方法
  • Array類:提供了動態(tài)創(chuàng)建數(shù)組驶沼,以及訪問數(shù)組的元素的靜態(tài)方法

在Java中,每個(gè)class都有一個(gè)相應(yīng)的Class對象争群。也就是說回怜,當(dāng)我們編寫一個(gè)類,編譯完成后换薄,在生成的.class文件中玉雾,就會產(chǎn)生一個(gè)Class對象,用于表示這個(gè)類的類型信息轻要。 java中的Class三種獲取方式:

//使用Class類的靜態(tài)方法forName()复旬,用類的名字獲取一個(gè)Class實(shí)例
Class<?> bookClass = Class.forName("cc.abto.demo.Book");

//利用對象調(diào)用getClass()方法獲取該對象的Class實(shí)例
Book book = new Book();
Class<? extends Book> bookClass = book.getClass();

//運(yùn)用.class的方式來獲取Class實(shí)例,對于基本數(shù)據(jù)類型的封裝類伦腐,還可以采用.TYPE來獲取相對應(yīng)的基本數(shù)據(jù)類型的Class實(shí)例
Class<Book> bookClass = Book.class;
Class<Integer> type = Integer.TYPE;

然后再貼一些常用的方法

    public Annotation[] getAnnotations () //獲取這個(gè)類中所有注解

    getClassLoader() //獲取加載這個(gè)類的類加載器

    getDeclaredMethods() //獲取這個(gè)類中的所有方法

    getReturnType() //獲取方法的返回類型

    getParameterTypes() //獲取方法的傳入?yún)?shù)類型

    isAnnotation() //測試這類是否是一個(gè)注解類

    getDeclaredConstructors() //獲取所有的構(gòu)造方法

    getDeclaredMethod(String name, Class… parameterTypes)// 獲取指定的構(gòu)造方法(參數(shù):參數(shù)類型.class)

    getSuperclass() //獲取這個(gè)類的父類

    getInterfaces()// 獲取這個(gè)類實(shí)現(xiàn)的所有接口

    getFields() //獲取這個(gè)類中所有被public修飾的成員變量

    getField(String name) //獲取指定名字的被public修飾的成員變量

    newInstance() //返回此Class所表示的類赢底,通過調(diào)用默認(rèn)的(即無參數(shù))構(gòu)造函數(shù)創(chuàng)建的一個(gè)新實(shí)例

更多的方法和方法的注解大家可以查看文檔。

Android中的簡單應(yīng)用

查看Android SDK的源碼時(shí)候柏蘑。你會發(fā)現(xiàn)很多類或方法中經(jīng)常加上了“@hide”注釋標(biāo)記幸冻,這些API是不允許在程序中調(diào)用的。Hidden API之所以被隱藏咳焚,是想阻止開發(fā)者使用SDK中那些未完成或不穩(wěn)定的部分(接口或架構(gòu))洽损。如圖所示



所以在開發(fā)中,我們不僅可以通過反射獲取私有屬性和方法革半,也可以利用反射獲取一些SDK對外部隱藏的API碑定,比如說前陣子在做藍(lán)牙開發(fā)的時(shí)候流码,自動配對的一些方法在API 19以后才對外開放的,這邊我們就可以使用反射來實(shí)現(xiàn)配對功能了

try
{
    Class<BluetoothDevice> bluetoothDeviceClass = BluetoothDevice.class;
    bluetoothDeviceClass.getMethod("setPin", byte[].class).invoke(device, "1234".getBytes());
    bluetoothDeviceClass.getMethod("createBond").invoke(device);
    bluetoothDeviceClass.getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
    bluetoothDeviceClass.getMethod("cancelPairingUserInput").invoke(device);

}
catch (Exception e)
{
    e.printStackTrace();
}

反射的好處

反射不僅可以讓我們獲得隱藏的方法和屬性延刘,還可以讓對象的實(shí)例化從編譯時(shí)轉(zhuǎn)化為運(yùn)行時(shí)漫试,因?yàn)槲覀兛梢酝ㄟ^Class.forName("cc.abto.demo.Book").newInstance()的方法來生成新的實(shí)例,而這邊的"cc.abto.demo.Book"是一個(gè)字符串碘赖,完全可以用變量來代替驾荣,再結(jié)合抽象工廠模式什么的,我們就可以很大程度上對程序應(yīng)用中的功能模塊進(jìn)行解耦合普泡〔ブ溃可能這邊簡單幾句沒能解釋清楚,大家可以看看《大話設(shè)計(jì)模式》之類的書撼班,里面就介紹的比較清楚明白了歧匈。

反射的弊端

反射帶來的兩大弊端可能就是安全和性能問題了吧,這方面我知之甚少砰嘁,有待進(jìn)一步的了解和學(xué)習(xí)件炉。

最后

因?yàn)樽约核接邢蓿绻行╁e(cuò)誤的地方還請大家見諒矮湘。下面貼出幾篇寫得比較好和詳細(xì)的博客妻率。
【Android】 認(rèn)識反射機(jī)制(Reflection)
Java反射機(jī)制的原理及在Android下的簡單應(yīng)用
java中的反射機(jī)制
Android注解與反射機(jī)制

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市板祝,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌走净,老刑警劉巖券时,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異伏伯,居然都是意外死亡橘洞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門说搅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來炸枣,“玉大人,你說我怎么就攤上這事弄唧∈食Γ” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵候引,是天一觀的道長侯养。 經(jīng)常有香客問我,道長澄干,這世上最難降的妖魔是什么逛揩? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任柠傍,我火速辦了婚禮,結(jié)果婚禮上辩稽,老公的妹妹穿的比我還像新娘惧笛。我一直安慰自己,他們只是感情好逞泄,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布患整。 她就那樣靜靜地躺著,像睡著了一般炭懊。 火紅的嫁衣襯著肌膚如雪并级。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天侮腹,我揣著相機(jī)與錄音嘲碧,去河邊找鬼。 笑死父阻,一個(gè)胖子當(dāng)著我的面吹牛愈涩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播加矛,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼履婉,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了斟览?” 一聲冷哼從身側(cè)響起毁腿,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎苛茂,沒想到半個(gè)月后已烤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡妓羊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年胯究,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片躁绸。...
    茶點(diǎn)故事閱讀 40,861評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡裕循,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出净刮,到底是詐尸還是另有隱情剥哑,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布庭瑰,位于F島的核電站星持,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏弹灭。R本人自食惡果不足惜督暂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一揪垄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逻翁,春花似錦饥努、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至缠诅,卻和暖如春溶浴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背管引。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工士败, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人褥伴。 一個(gè)月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓谅将,卻偏偏與公主長得像,于是被迫代替她去往敵國和親重慢。 傳聞我的和親對象是個(gè)殘疾皇子饥臂,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評論 2 361

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