反射入門

1、認識反射

“反”茬祷,有反就有“正”厂抖。正常情況先有類,再產(chǎn)生對象卧檐。所謂的反就是可以利用對象找到對象的出處:

在Object類里面提供有一個方法:取得Class對象:

public final Class getClass()墓懂;

可以輸出類的完整名稱,就找到了對象的出處霉囚。

Class類對象的實例化:

java.lang.Class是一個類捕仔。這個類是反射操作的源頭,所有的反射都要從此類開始進行。最關鍵的是這個類有三種實例化方式榜跌。

1闪唆、調(diào)用Object類中的getClass()方法:Class cls = mIntent.getClass();需要實例化對象钓葫,需要import導入類

2悄蕾、使用“類.class”取得:Class cls = Intent.class。不需要實例化對象础浮,需要import導入類

3帆调、調(diào)用Class類提供的方法:Class.forName(String className)。不需要import語句導入一個明確的類

反射實例化對象豆同。

當拿到一個類的時候番刊,肯定用關鍵字new進行對象的實例化操作,但是如果有了Class類對象后诱告,就可以不用New關鍵字也可以進行對象的實例化操作:

public T newInstance()相當于使用new調(diào)用無參構(gòu)造函數(shù)撵枢。

有了反射之后民晒,進行實例化的操作不再只是單單依靠關鍵字new完成了精居。反射也可以。

所以用反射獲取一個對象實例化的步驟為:

1潜必、先獲取Class類的實例化對象:Class cls = Class.forName(“xxxxxx”);

2靴姿、用Class類的實例化對象獲取制定類的實例化對象:Book book=(Book)cls.newInstance();


但是本來用關鍵字new一行代碼就可以完成實例化操作,反射需要兩步磁滚,這樣好嗎佛吓?


2、理解反射的作用

在任何開發(fā)中垂攘,一起的耦合都起源于new维雇。

看工程模式。如果想要擴展晒他,就必須改動工廠類中的if else吱型。如果一直擴展,就需要一直修改工廠類陨仅。因為工廠類中是通過New產(chǎn)生對象實例的津滞,所以New就是問題的關鍵。

如果工廠中用反射代替new灼伤,就不需要if else和new實例化每個if else中的對象触徐。只需要傳入類的完整名稱,就可以解耦和狐赡。擴展性非常的強撞鹉!

3、利用反射調(diào)用類的結(jié)構(gòu)

a、使用反射調(diào)用構(gòu)造:

之前所說的newInstance()方法實際上等于調(diào)用了無參構(gòu)造函數(shù)孔祸,但是實際中可能么有無參構(gòu)造函數(shù)隆敢,

Class中有方法可以取到構(gòu)造:public Constructor[]getConstructors():取得全部構(gòu)造。

和:public Constructor getConstructor(Class… paramterTypes):取得一個指定參數(shù)順序的構(gòu)造函數(shù)崔慧。

Constructor類是java.lang.reflect拂蝎,這時候真正到了反射中。

實例化對象方法public T newInstance(Object… initargs)

所以用反射獲取一個沒有無參構(gòu)造函數(shù)的類的實例化對象步驟為:

1惶室、先獲取Class類對象:Class cls = Class.forName(“xxxxx”);

2温自、獲取指定參數(shù)類型順序的構(gòu)造函數(shù):Constructor con = cls.getConstructor(Sring.class,double.class);

3、使用獲取到的構(gòu)造函數(shù)實例化對象:Object obj = con.newInstance(“第一個參數(shù)字符串類型”皇钞,10086.8)悼泌;

所以建議,不管有多少個構(gòu)造方法夹界,都盡量提供一個無參構(gòu)造函數(shù)馆里,不然太麻煩了。

b可柿、反射調(diào)用方法:

Class類中提供了一下方法用來獲取類的方法:

public Method[]getMethods()

public Method getMethod(String methodName,Class… paramterTypes)

Method類似java.lang.reflect包下的鸠踪,其中有個

public Object invoke(Object obj,Object… args)方法。

所以用反射調(diào)用方法的步驟為:

1复斥、先獲取Class對象:Class cls = Class.forName(“xxxxx”)营密;

并獲取對象Object object = cls.newInstance();//必須給出實例化對象

2、獲取指定方法:Method setTitleMethod = cls.getMethod(“setTitle”,String.class);

3目锭、調(diào)用方法:setTitleMethod.invoke(object,“一本書的標題”)评汰;//等價于Book對象.setTitle(“一本書的標題”)

但是這個過程中完全沒有出現(xiàn)過Book。也就是說痢虹,利用反射可以實現(xiàn)任意類的制定方法的調(diào)用被去。

c、反射調(diào)用成員:

類中的屬性一定要在本類實例化對象產(chǎn)生后才可以分配內(nèi)存空間奖唯。

Class類中提供了取得成員的方法:

1惨缆、取得全部成員:public Field[]getDeclaredFields()

2、取得指定成員:public Field getDeclaredField(String fieldName)

Field是java.lang.reflect包下臭埋。其中有:

1踪央、取得屬性內(nèi)容:public Object get(Object obj);

2、設置屬性內(nèi)容:public void set(Object obj,Object value)

所以反射調(diào)用成員的步驟為:

假設一個Book類瓢阴,里面只有一個屬性private String title;沒有getter/setter方法畅蹂。

1、先獲取Class對象:Class cls = Class.forName(“xxx”);

2荣恐、獲取對象:Object obj = cls.newInstance();

3液斜、獲取指定成員:Field titleField = cls.getDeclaredField(“title”);

4累贤、設置屬性內(nèi)容:titleField.set(obj,“書的名字”)少漆;//相當于:Book類對象.title =“書的名字“

但是調(diào)用get還是會報錯臼膏。因為封裝性。

這時候需要用到:AccessbleObject

在java.lang.reflect.AccessibleObject類下面(JDK1.8修改):

~ Executable//可執(zhí)行的

~ Constrictor

~Method

~Field

在這個類中有一個方法:

public void setAccessible(boolean flag)設置是否封裝示损,

設置為false后渗磅,就是取消封裝,這個時候再調(diào)用剛才的get就可以正常調(diào)用了检访。

構(gòu)造方法和普通方法一樣可以取消封裝始鱼,只不過很少這樣去做,而且對屬性的訪問還是應該是getter和setter方法完成脆贵。

學習完這些医清,反射算是入門了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末卖氨,一起剝皮案震驚了整個濱河市会烙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌筒捺,老刑警劉巖柏腻,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異焙矛,居然都是意外死亡葫盼,警方通過查閱死者的電腦和手機残腌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門村斟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人抛猫,你說我怎么就攤上這事蟆盹。” “怎么了闺金?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵逾滥,是天一觀的道長。 經(jīng)常有香客問我败匹,道長寨昙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任掀亩,我火速辦了婚禮舔哪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘槽棍。我一直安慰自己捉蚤,他們只是感情好抬驴,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缆巧,像睡著了一般布持。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上陕悬,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天题暖,我揣著相機與錄音,去河邊找鬼捉超。 笑死芙委,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的狂秦。 我是一名探鬼主播灌侣,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼裂问!你這毒婦竟也來了侧啼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤堪簿,失蹤者是張志新(化名)和其女友劉穎痊乾,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體椭更,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡哪审,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了虑瀑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片湿滓。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖舌狗,靈堂內(nèi)的尸體忽然破棺而出叽奥,到底是詐尸還是另有隱情,我是刑警寧澤痛侍,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布朝氓,位于F島的核電站,受9級特大地震影響主届,放射性物質(zhì)發(fā)生泄漏赵哲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一君丁、第九天 我趴在偏房一處隱蔽的房頂上張望枫夺。 院中可真熱鬧,春花似錦谈截、人聲如沸筷屡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽毙死。三九已至燎潮,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間扼倘,已是汗流浹背确封。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留再菊,地道東北人爪喘。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像纠拔,于是被迫代替她去往敵國和親秉剑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉稠诲,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,715評論 0 9
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理侦鹏,服務發(fā)現(xiàn),斷路器臀叙,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • 1. Java基礎部分 基礎部分的順序:基本語法略水,類相關的語法,內(nèi)部類的語法劝萤,繼承相關的語法渊涝,異常的語法,線程的語...
    子非魚_t_閱讀 31,631評論 18 399
  • 學習Android的同學注意了4蚕印?缡汀!學習過程中遇到什么問題或者想獲取學習資源的話既鞠,歡迎加入Android學習交流群...
    kingZXY2009閱讀 333評論 0 0
  • “你說胡離啊煤傍,我知道這個人盖文,每天晚上12點準時嘱蛋,他就會出現(xiàn)在這個街角,看起來像剛下班回家五续∪髅簦”街角的零售店老板說。 ...
    知魚君閱讀 188評論 0 1