??? 面對(duì)Java反射機(jī)制,會(huì)有種令人敬畏而又好奇的感覺,覺得非常強(qiáng)大,深不可測!呵,其實(shí)是懶惰的表現(xiàn),總是找借口和理由不去深入學(xué)習(xí)這些東西,覺得實(shí)際開發(fā)中很少會(huì)用到,能混就混混吧。真該死。
??? 下面就來淺談下反射,也總結(jié)下這幾天學(xué)習(xí)的心得,僅供個(gè)人總結(jié),不足之處請(qǐng)大家看在小弟能力有限學(xué)習(xí)未深的份上多多包涵呵。?
??? 每個(gè)class都其實(shí)都對(duì)應(yīng)一個(gè)Class對(duì)象,該對(duì)象就包含在我們編寫完一個(gè)類編譯之后在相應(yīng)的路徑下產(chǎn)生一個(gè).class文件中,該Class對(duì)象就用于表示這個(gè)類的類型信息。在運(yùn)行期間,如果我們要產(chǎn)生某個(gè)類的對(duì)象,Java虛擬機(jī)(JVM)會(huì)檢查該類型的Class對(duì)象是否已被加載。如果沒有被加載,JVM會(huì)根據(jù)類的名稱找到.class文件并加載它。一旦某個(gè)類型的Class對(duì)象已被加載到內(nèi)存,就可以用它來產(chǎn)生該類型的所有對(duì)象。
??? OK,初步了解了以上類的被加載機(jī)制后,我們就開談Java Reflect的樂趣吧。
??? Java不是動(dòng)態(tài)語言,但是通過java reflect我們可以實(shí)現(xiàn)類似動(dòng)態(tài)語言的特性,靠的是什么?就是java reflect API,而java reflect 靠的是什么?其根本就是從每個(gè)類所對(duì)應(yīng)的Class對(duì)象中所定義的各種方法。也就是說,要想對(duì)某個(gè)類使用反射機(jī)制動(dòng)態(tài)對(duì)其進(jìn)行某些特殊操作,我們必須先獲取該類所對(duì)象的Class對(duì)象,它就是反射的一個(gè)入口,怎么樣來獲取Class對(duì)象呢?有以下幾種常用的方法:
??? 1、利用對(duì)象調(diào)用getClass()方法獲取該對(duì)象的Class實(shí)例。打開JDK文檔,該方法定義在Object類中,也就是說,java中所有的類都擁有該方法,因?yàn)閖ava中任何對(duì)象都是延伸自O(shè)bject父類的。該方法返回Class對(duì)象,如果類型不確定,可以使用泛型Class<?>
???? 2、使用Class類的靜態(tài)方法forName(),用類的全路徑名字獲取一個(gè)Class實(shí)例。這個(gè)方法就不用多說了呵,初學(xué)Java JDBC時(shí)我們就用過,典型的反射應(yīng)用。
???? 3、運(yùn)用.class的方式來獲取Class實(shí)例,如(類名.class),對(duì)于基本數(shù)據(jù)類型的封裝類,還可以采用.TYPE來獲取相對(duì)應(yīng)的基本數(shù)據(jù)類型的Class實(shí)例。int.class ,Integre.class ,Integer.TYPE)
??? 好了,現(xiàn)在我們得到了一個(gè)類的Class對(duì)象了,那么該怎么下手哩?仔細(xì)想想,我們?cè)诙x一個(gè)類的時(shí)候,無非只有四種存在,
??? 1、Field : 屬性
??? 2、Constructor : 構(gòu)造子
??? 3、Method : 方法
??? 4、Array : 可能會(huì)定義的數(shù)組
??? 以上幾種就是我們?cè)陬惗x的時(shí)候類中存在最基本的元素,但反射是在運(yùn)行時(shí)對(duì)類對(duì)象進(jìn)行操作的,所以我們也有可能需要對(duì)某個(gè)屬性或方法的訪問權(quán)限進(jìn)行獲取,以對(duì)該對(duì)象更全面的了解,所以Modifier的獲取也是必然的。
??? 請(qǐng)打開JDK文檔的java.lang.reflect包,該包下就會(huì)找到上述幾個(gè)東東,原來在該反射包中,它們都被定義成類了,并且在每個(gè)類中都定義了對(duì)其操作的各種方法。有人可能要問了,這幾個(gè)類跟Class對(duì)象有什么關(guān)系?呵,關(guān)系大了去了,比如Constructor是構(gòu)造方法類,它一般用于構(gòu)造某個(gè)帶參構(gòu)造器類的對(duì)象的時(shí)候使用,比如某個(gè)類只提供了一個(gè)帶參構(gòu)造器,這時(shí)就需要使用該類的Class對(duì)象的getConstructor()方法返回Constructor對(duì)象,再用該對(duì)象的newInstance()方法來構(gòu)造該類。也就是說,以上幾個(gè)類,都是基于Class對(duì)象來對(duì)某個(gè)類進(jìn)行操作的。
??? 總之,Class代表的是類對(duì)象,上述幾個(gè)類可以看成是工具,我想怎么去對(duì)一個(gè)類對(duì)象在運(yùn)行時(shí)進(jìn)行操作,就是依靠該類的Class對(duì)象來告訴上述幾個(gè)類:“我想讓你(Field、Constructor、Method、Array、Modifier等)告訴我此時(shí)我代表的這個(gè)對(duì)象的某些信息,因?yàn)槲乙谶@個(gè)運(yùn)行時(shí)刻對(duì)它進(jìn)行一些操作!”
??? 所以,在java反射中,只要把這幾個(gè)類的關(guān)系及其作用弄清楚之后,對(duì)java反射也就有了一個(gè)大致的了解了,對(duì)于一些架構(gòu)或是開源框架的一些“智能”也就不會(huì)感到那么高深莫測了呵。其實(shí)java reflect技術(shù)是java中的核心機(jī)制,十分重要。小弟不才,說了半天沒表達(dá)清楚什么,繼續(xù)努力!
????
??? 下面就來淺談下反射,也總結(jié)下這幾天學(xué)習(xí)的心得,僅供個(gè)人總結(jié),不足之處請(qǐng)大家看在小弟能力有限學(xué)習(xí)未深的份上多多包涵呵。?
??? 每個(gè)class都其實(shí)都對(duì)應(yīng)一個(gè)Class對(duì)象,該對(duì)象就包含在我們編寫完一個(gè)類編譯之后在相應(yīng)的路徑下產(chǎn)生一個(gè).class文件中,該Class對(duì)象就用于表示這個(gè)類的類型信息。在運(yùn)行期間,如果我們要產(chǎn)生某個(gè)類的對(duì)象,Java虛擬機(jī)(JVM)會(huì)檢查該類型的Class對(duì)象是否已被加載。如果沒有被加載,JVM會(huì)根據(jù)類的名稱找到.class文件并加載它。一旦某個(gè)類型的Class對(duì)象已被加載到內(nèi)存,就可以用它來產(chǎn)生該類型的所有對(duì)象。
??? OK,初步了解了以上類的被加載機(jī)制后,我們就開談Java Reflect的樂趣吧。
??? Java不是動(dòng)態(tài)語言,但是通過java reflect我們可以實(shí)現(xiàn)類似動(dòng)態(tài)語言的特性,靠的是什么?就是java reflect API,而java reflect 靠的是什么?其根本就是從每個(gè)類所對(duì)應(yīng)的Class對(duì)象中所定義的各種方法。也就是說,要想對(duì)某個(gè)類使用反射機(jī)制動(dòng)態(tài)對(duì)其進(jìn)行某些特殊操作,我們必須先獲取該類所對(duì)象的Class對(duì)象,它就是反射的一個(gè)入口,怎么樣來獲取Class對(duì)象呢?有以下幾種常用的方法:
??? 1、利用對(duì)象調(diào)用getClass()方法獲取該對(duì)象的Class實(shí)例。打開JDK文檔,該方法定義在Object類中,也就是說,java中所有的類都擁有該方法,因?yàn)閖ava中任何對(duì)象都是延伸自O(shè)bject父類的。該方法返回Class對(duì)象,如果類型不確定,可以使用泛型Class<?>
???? 2、使用Class類的靜態(tài)方法forName(),用類的全路徑名字獲取一個(gè)Class實(shí)例。這個(gè)方法就不用多說了呵,初學(xué)Java JDBC時(shí)我們就用過,典型的反射應(yīng)用。
???? 3、運(yùn)用.class的方式來獲取Class實(shí)例,如(類名.class),對(duì)于基本數(shù)據(jù)類型的封裝類,還可以采用.TYPE來獲取相對(duì)應(yīng)的基本數(shù)據(jù)類型的Class實(shí)例。int.class ,Integre.class ,Integer.TYPE)
??? 好了,現(xiàn)在我們得到了一個(gè)類的Class對(duì)象了,那么該怎么下手哩?仔細(xì)想想,我們?cè)诙x一個(gè)類的時(shí)候,無非只有四種存在,
??? 1、Field : 屬性
??? 2、Constructor : 構(gòu)造子
??? 3、Method : 方法
??? 4、Array : 可能會(huì)定義的數(shù)組
??? 以上幾種就是我們?cè)陬惗x的時(shí)候類中存在最基本的元素,但反射是在運(yùn)行時(shí)對(duì)類對(duì)象進(jìn)行操作的,所以我們也有可能需要對(duì)某個(gè)屬性或方法的訪問權(quán)限進(jìn)行獲取,以對(duì)該對(duì)象更全面的了解,所以Modifier的獲取也是必然的。
??? 請(qǐng)打開JDK文檔的java.lang.reflect包,該包下就會(huì)找到上述幾個(gè)東東,原來在該反射包中,它們都被定義成類了,并且在每個(gè)類中都定義了對(duì)其操作的各種方法。有人可能要問了,這幾個(gè)類跟Class對(duì)象有什么關(guān)系?呵,關(guān)系大了去了,比如Constructor是構(gòu)造方法類,它一般用于構(gòu)造某個(gè)帶參構(gòu)造器類的對(duì)象的時(shí)候使用,比如某個(gè)類只提供了一個(gè)帶參構(gòu)造器,這時(shí)就需要使用該類的Class對(duì)象的getConstructor()方法返回Constructor對(duì)象,再用該對(duì)象的newInstance()方法來構(gòu)造該類。也就是說,以上幾個(gè)類,都是基于Class對(duì)象來對(duì)某個(gè)類進(jìn)行操作的。
??? 總之,Class代表的是類對(duì)象,上述幾個(gè)類可以看成是工具,我想怎么去對(duì)一個(gè)類對(duì)象在運(yùn)行時(shí)進(jìn)行操作,就是依靠該類的Class對(duì)象來告訴上述幾個(gè)類:“我想讓你(Field、Constructor、Method、Array、Modifier等)告訴我此時(shí)我代表的這個(gè)對(duì)象的某些信息,因?yàn)槲乙谶@個(gè)運(yùn)行時(shí)刻對(duì)它進(jìn)行一些操作!”
??? 所以,在java反射中,只要把這幾個(gè)類的關(guān)系及其作用弄清楚之后,對(duì)java反射也就有了一個(gè)大致的了解了,對(duì)于一些架構(gòu)或是開源框架的一些“智能”也就不會(huì)感到那么高深莫測了呵。其實(shí)java reflect技術(shù)是java中的核心機(jī)制,十分重要。小弟不才,說了半天沒表達(dá)清楚什么,繼續(xù)努力!
????
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

