Java 反射機(jī)制

Java 反射機(jī)制

什么是反射

Java 反射是Java語(yǔ)言的一個(gè)很重要的特征族淮,它使得Java具體了“動(dòng)態(tài)性”受神。

反射主要是指程序可以訪(fǎng)問(wèn)卵慰、檢測(cè)和修改它本身狀態(tài)或行為的一種能力抬吟。在計(jì)算機(jī)科學(xué)領(lǐng)域渐行,反射是一類(lèi)應(yīng)用弛针,它們能夠自描述和自控制叠骑。這類(lèi)應(yīng)用通過(guò)某種機(jī)制來(lái)實(shí)現(xiàn)對(duì)自己行為的描述和檢測(cè),并能根據(jù)自身行為的狀態(tài)和結(jié)果削茁,調(diào)整或修改應(yīng)用所描述行為的狀態(tài)和相關(guān)的語(yǔ)義宙枷。

在Java中的反射機(jī)制,被稱(chēng)為Reflection茧跋。(大家看到這個(gè)單詞慰丛,第一個(gè)想法應(yīng)該就是去開(kāi)發(fā)文檔中搜一下了。)它允許運(yùn)行中的Java程序?qū)ψ陨磉M(jìn)行檢查瘾杭,并能直接操作程序的內(nèi)部屬性或方法诅病。Reflection機(jī)制允許程序在正在執(zhí)行的過(guò)程中,利用Reflection APIs取得任何已知名稱(chēng)的類(lèi)的內(nèi)部信息,包括:package贤笆、 type parameters蝇棉、 superclass、 implemented interfaces芥永、 inner classes银萍、 outer classes、 fields恤左、 constructors贴唇、 methods、 modifiers等飞袋,并可以在執(zhí)行的過(guò)程中戳气,動(dòng)態(tài)生成Instances、變更fields內(nèi)容或喚起methods巧鸭。

Java 反射機(jī)制主要提供了以下功能

  • 在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類(lèi)瓶您。

  • 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類(lèi)的對(duì)象。

  • 在運(yùn)行時(shí)判斷任意一個(gè)類(lèi)所具有的成員變量和方法纲仍。

  • 在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法呀袱。

簡(jiǎn)單應(yīng)用

  1. 通過(guò)Class類(lèi)獲取成員變量、成員方法郑叠、接口夜赵、超類(lèi)、構(gòu)造方法等
  • 運(yùn)行時(shí)復(fù)制對(duì)象

  • 用反射機(jī)制調(diào)用對(duì)象的方法

  • 動(dòng)態(tài)創(chuàng)建和訪(fǎng)問(wèn)數(shù)組

  • 運(yùn)行時(shí)變更field內(nèi)容

Java 反射

核心類(lèi)乡革,位于java.lang.reflect包中

  • Class類(lèi):代表一個(gè)類(lèi)寇僧。

  • Field 類(lèi):代表類(lèi)的成員變量(成員變量也稱(chēng)為類(lèi)的屬性)。

  • Method類(lèi):代表類(lèi)的方法沸版。

  • Constructor 類(lèi):代表類(lèi)的構(gòu)造方法嘁傀。

  • Array類(lèi):提供了動(dòng)態(tài)創(chuàng)建數(shù)組,以及訪(fǎng)問(wèn)數(shù)組的元素的靜態(tài)方法视粮。

核心 API

在 java.lang.Object 類(lèi)中定義了getClass()方法细办,因此對(duì)于任意一個(gè)Java對(duì)象,都可以通過(guò)此方法獲得對(duì)象的類(lèi)型蕾殴。

獲取類(lèi)的完整名字

  • public String getName() :獲得類(lèi)的完整名字笑撞。

獲取構(gòu)造方法

  • Constructor getConstructor(Class[] params) 根據(jù)構(gòu)造函數(shù)的參數(shù),返回一個(gè)具體的具有public屬性的構(gòu)造函數(shù)

  • Constructor getConstructors() 返回所有具有public屬性的構(gòu)造函數(shù)數(shù)組

  • Constructor getDeclaredConstructor(Class[] params) 根據(jù)構(gòu)造函數(shù)的參數(shù)区宇,返回一個(gè)具體的構(gòu)造函數(shù)(不分public和非public屬性)

  • Constructor getDeclaredConstructors() 返回該類(lèi)中所有的構(gòu)造函數(shù)數(shù)組(不分public和非public屬性)

獲取類(lèi)的成員方法

  • Method getMethod(String name, Class[] parameterTypes) 根據(jù)方法名和參數(shù)娃殖,返回一個(gè)具體的具有public屬性的方法

  • Method[] getMethods() 返回所有具有public屬性的方法數(shù)組

  • Method getDeclaredMethod(String name, Class[] params) 根據(jù)方法名和參數(shù)值戳,返回一個(gè)具體的方法(不分public和非public屬性)

  • Method[] getDeclaredMethods() 返回該類(lèi)中的所有的方法數(shù)組(不分public和非public屬性),不包含繼承來(lái)的方法

獲取類(lèi)的成員變量(成員屬性)

  • Field getField(String name) 根據(jù)變量名议谷,返回一個(gè)具體的具有public屬性的成員變量

  • Field[] getFields() 返回具有public屬性的成員變量的數(shù)組

  • Field getDeclaredField(String name) 根據(jù)變量名,返回一個(gè)成員變量(不分public和非public屬性)

  • Field[] getDelcaredField() 返回所有成員變量組成的數(shù)組(不分public和非public屬性)

獲取類(lèi)堕虹、屬性卧晓、方法的修飾域

類(lèi)Class芬首、Method、Constructor逼裆、Field都有一個(gè)public方法int getModifiers()郁稍。該方法返回一個(gè)int類(lèi)型的數(shù),表示被修飾對(duì)象( Class胜宇、 Method耀怜、 Constructor、 Field )的修飾類(lèi)型的組合值桐愉。


//打印輸出方法的修飾域

int mod = methods[i].getModifiers();

System.out.print(Modifier.toString(mod) + "");

創(chuàng)建類(lèi)的一個(gè)實(shí)例


// 利用newInstance()方法财破,獲取構(gòu)造方法的實(shí)例

Object obj = cls.newInstance();

// Class的newInstance方法,僅提供默認(rèn)無(wú)參的實(shí)例化方法从诲,類(lèi)似于無(wú)參的構(gòu)造方法

// Constructor的newInstance方法左痢,提供了帶參數(shù)的實(shí)例化方法,類(lèi)似于含參的構(gòu)造方法

Constructor ct = cls.getConstructor(null);

Object obj = ct.newInstance(null);

調(diào)用方法

  • public Object invoke(Object obj, Object... args) 調(diào)用靜態(tài)方法時(shí)系洛,第一個(gè)參數(shù)為 null

  • public void setAccessible(boolean flag) 可以改變私有方法的權(quán)限

原理

java虛擬機(jī)有一個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)俊性,這個(gè)數(shù)據(jù)區(qū)又被分為方法區(qū),堆區(qū)和棧區(qū)描扯,我們這里需要了解的主要是方法區(qū)定页。方法區(qū)的主要作用是存儲(chǔ)被裝載的類(lèi)的類(lèi)型信息,當(dāng)java虛擬機(jī)裝載某個(gè)類(lèi)型的時(shí)候绽诚,需要類(lèi)裝載器定位相應(yīng)的class文件拯勉,然后將其讀入到j(luò)ava虛擬機(jī)中,緊接著虛擬機(jī)提取class中的類(lèi)型信息憔购,將這些信息存儲(chǔ)到方法區(qū)中宫峦。這些信息主要包括:

  • 這個(gè)類(lèi)型的全限定名

  • 這個(gè)類(lèi)型的直接超類(lèi)的全限定名

  • 這個(gè)類(lèi)型是類(lèi)類(lèi)型還是接口類(lèi)型

  • 這個(gè)類(lèi)型的訪(fǎng)問(wèn)修飾符

  • 任何直接超接口的全限定名的有序列表

  • 該類(lèi)型的常量池

  • 字段信息

  • 方法信息

  • 除了常量以外的所有類(lèi)變量

  • 一個(gè)到class類(lèi)的引用

應(yīng)用

解析 Json 格式數(shù)據(jù),并利用反射創(chuàng)建對(duì)應(yīng)對(duì)象

利用反射調(diào)用私有方法


import java.lang.reflect.Constructor;

import java.lang.reflect.Method;

public class LoadMethodEx {

/**

* 在運(yùn)行時(shí)加載指定的類(lèi)玫鸟,并調(diào)用指定的方法

* @param cName            Java的類(lèi)名

* @param MethodName    方法名

* @param params        方法的參數(shù)值

* @return

*/

public Object Load(String cName, String MethodName, Object[] params) {

Object retObject = null;

try {

// 加載指定的類(lèi)

Class cls = Class.forName(cName);    // 獲取Class類(lèi)的對(duì)象的方法之二

// 利用newInstance()方法导绷,獲取構(gòu)造方法的實(shí)例

// Class的newInstance方法只提供默認(rèn)無(wú)參構(gòu)造實(shí)例

// Constructor的newInstance方法提供帶參的構(gòu)造實(shí)例

Constructor ct = cls.getConstructor(null);

Object obj = ct.newInstance(null);

//Object obj = cls.newInstance();

// 根據(jù)方法名獲取指定方法的參數(shù)類(lèi)型列表

Class paramTypes[] = this.getParamTypes(cls, MethodName);

// 獲取指定方法

Method meth = cls.getMethod(MethodName, paramTypes);

meth.setAccessible(true);

// 調(diào)用指定的方法并獲取返回值為Object類(lèi)型

retObject = meth.invoke(obj, params);

} catch (Exception e) {

System.err.println(e);

}

return retObject;

}

/**

* 獲取參數(shù)類(lèi)型,返回值保存在Class[]中

*/

public Class[] getParamTypes(Class cls, String mName) {

Class[] cs = null;

/*

* Note: 由于我們一般通過(guò)反射機(jī)制調(diào)用的方法屎飘,是非public方法

* 所以在此處使用了getDeclaredMethods()方法

*/

Method[] mtd = cls.getDeclaredMethods();

for (int i = 0; i < mtd.length; i++) {

if (!mtd[i].getName().equals(mName)) {    // 不是我們需要的參數(shù)妥曲,則進(jìn)入下一次循環(huán)

continue;

}

cs = mtd[i].getParameterTypes();

}

return cs;

}

}

參考:
http://www.cnblogs.com/crazypebble/archive/2011/04/13/2014582.html
http://lavasoft.blog.51cto.com/62575/43218

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市钦购,隨后出現(xiàn)的幾起案子檐盟,更是在濱河造成了極大的恐慌,老刑警劉巖押桃,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葵萎,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)羡忘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)谎痢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人卷雕,你說(shuō)我怎么就攤上這事节猿。” “怎么了漫雕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵滨嘱,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我浸间,道長(zhǎng)九孩,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任发框,我火速辦了婚禮躺彬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘梅惯。我一直安慰自己宪拥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布铣减。 她就那樣靜靜地躺著她君,像睡著了一般。 火紅的嫁衣襯著肌膚如雪葫哗。 梳的紋絲不亂的頭發(fā)上缔刹,一...
    開(kāi)封第一講書(shū)人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音劣针,去河邊找鬼校镐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛捺典,可吹牛的內(nèi)容都是我干的鸟廓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼襟己,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼引谜!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起擎浴,我...
    開(kāi)封第一講書(shū)人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤员咽,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后贮预,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體贝室,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡契讲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了档玻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡茫藏,死狀恐怖误趴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情务傲,我是刑警寧澤凉当,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站售葡,受9級(jí)特大地震影響看杭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜挟伙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一楼雹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尖阔,春花似錦贮缅、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至齿坷,卻和暖如春桂肌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背永淌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工崎场, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人遂蛀。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓照雁,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親答恶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子饺蚊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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