反射入門

1、認(rèn)識(shí)反射

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

在Object類里面提供有一個(gè)方法:取得Class對(duì)象:

public final Class getClass();

可以輸出類的完整名稱,就找到了對(duì)象的出處。

Class類對(duì)象的實(shí)例化:

java.lang.Class是一個(gè)類。這個(gè)類是反射操作的源頭,所有的反射都要從此類開(kāi)始進(jìn)行。最關(guān)鍵的是這個(gè)類有三種實(shí)例化方式。

1、調(diào)用Object類中的getClass()方法:Class cls = mIntent.getClass();需要實(shí)例化對(duì)象,需要import導(dǎo)入類

2、使用“類.class”取得:Class cls = Intent.class。不需要實(shí)例化對(duì)象,需要import導(dǎo)入類

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

反射實(shí)例化對(duì)象。

當(dāng)拿到一個(gè)類的時(shí)候,肯定用關(guān)鍵字new進(jìn)行對(duì)象的實(shí)例化操作,但是如果有了Class類對(duì)象后,就可以不用New關(guān)鍵字也可以進(jìn)行對(duì)象的實(shí)例化操作:

public T newInstance()相當(dāng)于使用new調(diào)用無(wú)參構(gòu)造函數(shù)。

有了反射之后,進(jìn)行實(shí)例化的操作不再只是單單依靠關(guān)鍵字new完成了。反射也可以。

所以用反射獲取一個(gè)對(duì)象實(shí)例化的步驟為:

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

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


但是本來(lái)用關(guān)鍵字new一行代碼就可以完成實(shí)例化操作,反射需要兩步,這樣好嗎?


2、理解反射的作用

在任何開(kāi)發(fā)中,一起的耦合都起源于new。

看工程模式。如果想要擴(kuò)展,就必須改動(dòng)工廠類中的if else。如果一直擴(kuò)展,就需要一直修改工廠類。因?yàn)楣S類中是通過(guò)New產(chǎn)生對(duì)象實(shí)例的,所以New就是問(wèn)題的關(guān)鍵。

如果工廠中用反射代替new,就不需要if else和new實(shí)例化每個(gè)if else中的對(duì)象。只需要傳入類的完整名稱,就可以解耦和。擴(kuò)展性非常的強(qiáng)!

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

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

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

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

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

Constructor類是java.lang.reflect,這時(shí)候真正到了反射中。

實(shí)例化對(duì)象方法public T newInstance(Object… initargs)

所以用反射獲取一個(gè)沒(méi)有無(wú)參構(gòu)造函數(shù)的類的實(shí)例化對(duì)象步驟為:

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

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

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

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

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

Class類中提供了一下方法用來(lái)獲取類的方法:

public Method[]getMethods()

public Method getMethod(String methodName,Class… paramterTypes)

Method類似java.lang.reflect包下的,其中有個(gè)

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

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

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

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

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

3、調(diào)用方法:setTitleMethod.invoke(object,“一本書的標(biāo)題”);//等價(jià)于Book對(duì)象.setTitle(“一本書的標(biāo)題”)

但是這個(gè)過(guò)程中完全沒(méi)有出現(xiàn)過(guò)Book。也就是說(shuō),利用反射可以實(shí)現(xiàn)任意類的制定方法的調(diào)用。

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

類中的屬性一定要在本類實(shí)例化對(duì)象產(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、設(shè)置屬性內(nèi)容:public void set(Object obj,Object value)

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

假設(shè)一個(gè)Book類,里面只有一個(gè)屬性private String title;沒(méi)有g(shù)etter/setter方法。

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

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

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

4、設(shè)置屬性內(nèi)容:titleField.set(obj,“書的名字”);//相當(dāng)于:Book類對(duì)象.title =“書的名字“

但是調(diào)用get還是會(huì)報(bào)錯(cuò)。因?yàn)榉庋b性。

這時(shí)候需要用到:AccessbleObject

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

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

~ Constrictor

~Method

~Field

在這個(gè)類中有一個(gè)方法:

public void setAccessible(boolean flag)設(shè)置是否封裝,

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

構(gòu)造方法和普通方法一樣可以取消封裝,只不過(guò)很少這樣去做,而且對(duì)屬性的訪問(wèn)還是應(yīng)該是getter和setter方法完成。

學(xué)習(xí)完這些,反射算是入門了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,032評(píng)論 0 9
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,627評(píng)論 18 399
  • 學(xué)習(xí)Android的同學(xué)注意了!??!學(xué)習(xí)過(guò)程中遇到什么問(wèn)題或者想獲取學(xué)習(xí)資源的話,歡迎加入Android學(xué)習(xí)交流群...
    kingZXY2009閱讀 353評(píng)論 0 0
  • “你說(shuō)胡離啊,我知道這個(gè)人,每天晚上12點(diǎn)準(zhǔn)時(shí),他就會(huì)出現(xiàn)在這個(gè)街角,看起來(lái)像剛下班回家?!苯纸堑牧闶鄣昀习逭f(shuō)。 ...
    知魚君閱讀 215評(píng)論 0 1

友情鏈接更多精彩內(nèi)容