版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
本文格式為Word版,下載可任意編輯——深入理解java的反射深入理解java的反射
要想理解反射的原理,首先要了解什么是類型信息。Java讓我們?cè)谶\(yùn)行時(shí)識(shí)別對(duì)象和類的信息,主要有2種方式:一種是傳統(tǒng)的RTTI,它假定我們?cè)诰幾g時(shí)已經(jīng)知道了全體的類型信息;另一種是反射機(jī)制,它允許我們?cè)谶\(yùn)行時(shí)察覺(jué)和使用類的信息。
1、Class對(duì)象
理解RTTI在Java中的工作原理,首先需要知道類型信息在運(yùn)行時(shí)是如何表示的,這是由Class對(duì)象來(lái)完成的,它包含了與類有關(guān)的信息。Class對(duì)象就是用來(lái)創(chuàng)造全體“常規(guī)”對(duì)象的,Java使用Class對(duì)象來(lái)執(zhí)行RTTI,即使你正在執(zhí)行的是類似類型轉(zhuǎn)換這樣的操作。
每個(gè)類都會(huì)產(chǎn)生一個(gè)對(duì)應(yīng)的Class對(duì)象,也就是保存在.class文件。全體類都是在對(duì)其第一次使用時(shí),動(dòng)態(tài)加載到JVM的,當(dāng)程序創(chuàng)造一個(gè)對(duì)類的靜態(tài)成員的引用時(shí),就會(huì)加載這個(gè)類。Class對(duì)象僅在需要的時(shí)候才會(huì)加載,static初始化是在類加載時(shí)舉行的。
publicclassTestMainpublicstaticvoidmainString[]argsSystem.out.printlnXYZ.name;classXYZpublicstaticStringname=luoxn28;staticSystem.out.printlnxyz靜態(tài)塊;publicXYZSystem.out.printlnxyz構(gòu)造了;
輸出結(jié)果為:
類加載器首先會(huì)檢查這個(gè)類的Class對(duì)象是否已被加載過(guò),假設(shè)尚未加載,默認(rèn)的類加載器就會(huì)根據(jù)類名查找對(duì)應(yīng)的.class文件。
想在運(yùn)行時(shí)使用類型信息,務(wù)必獲取對(duì)象譬如類Base對(duì)象的Class對(duì)象的`引用,使用功能Class.forName“Base”可以實(shí)現(xiàn)該目的,或者使用base.class。留神,有一點(diǎn)很好玩,使用功能”.class”來(lái)創(chuàng)造Class對(duì)象的引用時(shí),不會(huì)自動(dòng)初始化該Class對(duì)象,使用forName會(huì)自動(dòng)初始化該Class對(duì)象。為了使用類而做的打定工作一般有以下3個(gè)步驟:
加載:由類加載器完成,找到對(duì)應(yīng)的字節(jié)碼,創(chuàng)造一個(gè)Class對(duì)象
鏈接:驗(yàn)證類中的字節(jié)碼,為靜態(tài)域調(diào)配空間
初始化:假設(shè)該類有超類,那么對(duì)其初始化,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化塊
publicclassBasestaticintnum=1;staticSystem.out.printlnBase+num;publicclassMainpublicstaticvoidmainString[]args//不會(huì)初始化靜態(tài)塊Classclazz1=Base.class;System.out.println;//會(huì)初始化Classclazz2=Class.forNamezzz.Base;
2、類型轉(zhuǎn)換前先做檢查
編譯器將檢查類型向下轉(zhuǎn)型是否合法,假設(shè)不合法將拋出奇怪。向下轉(zhuǎn)換類型前,可以使用instanceof判斷。
classBaseclassDerivedextendsBasepublicclassMainpublicstaticvoidmainString[]argsBasebase=newDerived;ifbaseinstanceofDerived//這里可以向下轉(zhuǎn)換了System.out.printlnok;elseSystem.out.printlnnotok;
3、反射:運(yùn)行時(shí)類信息
假設(shè)不知道某個(gè)對(duì)象確實(shí)切類型,RTTI可以報(bào)告你,但是有一個(gè)前提:這個(gè)類型在編譯時(shí)務(wù)必已知,這樣才能使用RTTI來(lái)識(shí)別它。Class類與java.lang.reflect類庫(kù)一起對(duì)反射舉行了支持,該類庫(kù)包含F(xiàn)ield、Method和Constructor類,這些類的對(duì)象由JVM在啟動(dòng)時(shí)創(chuàng)造,用以表示未知類里對(duì)應(yīng)的成員。這樣的話就可以使用Contructor創(chuàng)造新的對(duì)象,用get和set方法獲取和修改類中與Field對(duì)象關(guān)聯(lián)的字段,用invoke方法調(diào)用與Method對(duì)象關(guān)聯(lián)的方法。另外,還可以調(diào)用getFields、getMethods和getConstructors等大量便利的方法,以返回表示字段、方法、以及構(gòu)造器對(duì)象的數(shù)組,這樣,對(duì)象信息可以在運(yùn)行時(shí)被完全確定下來(lái),而在編譯時(shí)不需要知道關(guān)于類的任何事情。
反射機(jī)制并沒(méi)有什么神秘之處,當(dāng)通過(guò)反射與一個(gè)未知類型的對(duì)象打交道時(shí),JVM只是簡(jiǎn)樸地檢查這個(gè)對(duì)象,看它屬于哪個(gè)特定的類。因此,那個(gè)類的.class對(duì)于JVM來(lái)說(shuō)務(wù)必是可獲取的,要么在本地機(jī)器上,要么從網(wǎng)絡(luò)獲取。所以對(duì)于RTTI和反射之間的真正識(shí)別只在于:
RTTI,編譯器在編譯時(shí)開(kāi)啟和檢查.class文件
反射,運(yùn)行時(shí)開(kāi)啟和檢查.class文件
publicclassPersonimplementsSerializableprivateStringname;privateintage;//get/set方法publicstaticvoidmainString[]argsPersonperson=newPersonluoxn28,23;Classclazz=person.getClass;Field[]fields=clazz.getDeclaredFields;forFieldfield:fieldsStringkey=field.getName;PropertyDescriptordescriptor=newPropertyDescriptorkey,clazz;Methodmethod=descriptor.getReadMethod;Objectvalue=method.invokeperson;System.out.printlnkey+:+value;
以上通過(guò)getReadMethod方法調(diào)用類的get函數(shù),可以通過(guò)getWriteMethod方法來(lái)調(diào)用類的set方法。通常來(lái)說(shuō),我們不需要使用反射工具,但是它們?cè)趧?chuàng)造動(dòng)態(tài)代碼會(huì)更有用,反射在Java中用來(lái)支持其他特性的,例如對(duì)象的序列化和JavaBean等。
4、動(dòng)態(tài)代理
代理模式是為了供給額外或不同的操作,而插入的用來(lái)替代”實(shí)際”對(duì)象的對(duì)象,這些操作涉及到與”實(shí)際”對(duì)象的通信,因此代理通常充當(dāng)中間人角色。Java的動(dòng)態(tài)代理比代理的思想更前進(jìn)了一步,它可以動(dòng)態(tài)地創(chuàng)造并代理并動(dòng)態(tài)地處理對(duì)所代理方法的調(diào)用。在動(dòng)態(tài)代理上所做的全體調(diào)用都會(huì)被重定向到單一的調(diào)用處理器上,它的工作是透露調(diào)用的類型并確定相應(yīng)的策略。以下是一個(gè)動(dòng)態(tài)代理例如:
接口和實(shí)現(xiàn)類:
publicinterfaceInterfacevoiddoSomething;voidsomethingElseStringarg;publicclassRealObjectimplementsInterfacepublicvoiddoSomethingSystem.out.printlndoSomething.;publicvoidsomethingElseStringargSystem.out.printlnsomethingElse+arg;
動(dòng)態(tài)代理對(duì)象處理器:
publicclassDynamicProxyHandlerimplementsInvocationHandlerprivateObjectproxyed;publicDynamicProxyHandlerOxyed=proxyed;@OverridepublicObjectinvokeObjectproxy,Methodmethod,Object[]argsthrowsIllegalAccessException,IllegalArgumentException,InvocationTargetExceptionSystem.out.println代理工作了.;returnmethod.invokeproxyed,args;
測(cè)試類:
publicclassMainpublicstaticvoidmainString[]argsRealObjectreal=newRealObject;Interfaceproxy=InterfaceProxy.newProxyInstanceInterface.class.getClassLoader,newClass[]Interface.class,newDynamicProxyHandlerreal;proxy.doSomething;proxy.somethingElseluoxn28;
輸出結(jié)果如下:
通過(guò)調(diào)用Proxy靜態(tài)方法Proxy.newProxyInstance可以創(chuàng)造動(dòng)態(tài)代理,這個(gè)方法需要得到一個(gè)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 幼兒園月教學(xué)計(jì)劃模板
- 醫(yī)院護(hù)士年度計(jì)劃范本
- 大班表演游戲計(jì)劃
- 農(nóng)村綜治宣傳月的工作計(jì)劃
- 度班組長(zhǎng)工作計(jì)劃
- 客服員工作計(jì)劃
- 《GDP與GNP的區(qū)別》課件
- 醫(yī)院醫(yī)保年終工作計(jì)劃總結(jié)
- 《行為應(yīng)用分析》課件
- 2020版 滬教版 高中音樂(lè) 必修1 音樂(lè)鑒賞 下篇《第八單元 不忘初心》大單元整體教學(xué)設(shè)計(jì)2020課標(biāo)
- 二年級(jí)數(shù)學(xué)上冊(cè)口算天天練
- 2024國(guó)家開(kāi)放大學(xué)電大本科《液壓氣動(dòng)技術(shù)》期末試題及答案
- 商務(wù)服務(wù)機(jī)器人技術(shù)現(xiàn)狀與未來(lái)發(fā)展趨勢(shì)研究
- 工業(yè)物聯(lián)網(wǎng)(IIoT)行業(yè)發(fā)展全景調(diào)研與投資趨勢(shì)預(yù)測(cè)研究報(bào)告
- 金融數(shù)據(jù)分析-以Python為工具 課件 一、金融數(shù)據(jù)分析概覽
- 佛山市、三水區(qū)2022-2023學(xué)年七年級(jí)上學(xué)期期末地理試題【帶答案】
- 2024屆湖北高三元月調(diào)考數(shù)學(xué)試卷含答案
- DL∕T 1476-2023電力安全工器具預(yù)防性試驗(yàn)規(guī)程
- 西方園林史智慧樹(shù)知到期末考試答案章節(jié)答案2024年內(nèi)蒙古農(nóng)業(yè)大學(xué)
- 學(xué)年上學(xué)期期末職業(yè)高中高二年級(jí)數(shù)學(xué)練習(xí)試卷2
- 工程部設(shè)計(jì)部崗位職責(zé)
評(píng)論
0/150
提交評(píng)論