版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
Java反射機制與動態(tài)代理版權(quán)歸浪曦視頻在線所有Java反射機制與動態(tài)代理版權(quán)歸浪曦視第2頁概述本課程主要講述Java反射機制與設(shè)計模式之一:代理模式的原理與應(yīng)用同時詳細講述了Java對代理模式的支持以及Java中動態(tài)代理的原理,應(yīng)用與實踐本課程要求大家對Java泛型知識有所了解,因為程序代碼中大量使用了泛型相關(guān)知識,對于不熟悉該部分內(nèi)容的讀者,我會在下次課程中對JDK5.0中的新特性進行講解第2頁概述本課程主要講述Java反射機制與設(shè)計模式第3頁目錄Java反射機制代理模式第3頁目錄Java反射機制第4頁Java語言的反射機制在Java運行時環(huán)境中,對于任意一個類,能否知道這個類有哪些屬性和方法?對于任意一個對象,能否調(diào)用它的任意一個方法?答案是肯定的。這種動態(tài)獲取類的信息以及動態(tài)調(diào)用對象的方法的功能來自于Java語言的反射(Reflection)機制。Java反射機制主要提供了以下功能第4頁Java語言的反射機制在Java運行時環(huán)境中,對于任第5頁Java語言的反射機制在運行時判斷任意一個對象所屬的類。在運行時構(gòu)造任意一個類的對象。在運行時判斷任意一個類所具有的成員變量和方法。在運行時調(diào)用任意一個對象的方法第5頁Java語言的反射機制在運行時判斷任意一個對象所屬的第6頁Java語言的反射機制Reflection是Java被視為動態(tài)(或準動態(tài))語言的一個關(guān)鍵性質(zhì)。這個機制允許程序在運行時透過ReflectionAPIs取得任何一個已知名稱的class的內(nèi)部信息,包括其modifiers(諸如public,static等等)、superclass(例如Object)、實現(xiàn)之interfaces(例如Serializable),也包括fields和methods的所有信息,并可于運行時改變fields內(nèi)容或調(diào)用methods第6頁Java語言的反射機制Reflection是Jav第7頁Java語言的反射機制一般而言,開發(fā)者社群說到動態(tài)語言,大致認同的一個定義是:“程序運行時,允許改變程序結(jié)構(gòu)或變量類型,這種語言稱為動態(tài)語言”。從這個觀點看,Perl,Python,Ruby是動態(tài)語言,C++,Java,C#不是動態(tài)語言第7頁Java語言的反射機制一般而言,開發(fā)者社群說到動態(tài)語第8頁Java語言的反射機制盡管在這樣的定義與分類下Java不是動態(tài)語言,它卻有著一個非常突出的動態(tài)相關(guān)機制:Reflection。這個字的意思是“反射、映象、倒影”,用在Java身上指的是我們可以于運行時加載、探知、使用編譯期間完全未知的classes。換句話說,Java程序可以加載一個運行時才得知名稱的class,獲悉其完整構(gòu)造(但不包括methods定義),并生成其對象實體、或?qū)ζ鋐ields設(shè)值、或喚起其methods。這種“看透class”的能力(theabilityoftheprogramtoexamineitself)被稱為introspection(內(nèi)省、內(nèi)觀、反省)。Reflection和introspection是常被并提的兩個術(shù)語第8頁Java語言的反射機制盡管在這樣的定義與分類下Jav第9頁JavaReflectionAPI簡介在JDK中,主要由以下類來實現(xiàn)Java反射機制,這些類都位于java.lang.reflect包中Class類:代表一個類。Field類:代表類的成員變量(成員變量也稱為類的屬性)。Method類:代表類的方法。Constructor類:代表類的構(gòu)造方法。Array類:提供了動態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組的元素的靜態(tài)方法第9頁JavaReflectionAPI簡介在JDK中第10頁JavaReflectionAPI簡介例程DumpMethods類演示了ReflectionAPI的基本作用,它讀取命令行參數(shù)指定的類名,然后打印這個類所具有的方法信息第10頁JavaReflectionAPI簡介例程Du第11頁JavaReflectionAPI簡介例程ReflectTester類進一步演示了ReflectionAPI的基本使用方法。ReflectTester類有一個copy(Objectobject)方法,這個方法能夠創(chuàng)建一個和參數(shù)object同樣類型的對象,然后把object對象中的所有屬性拷貝到新建的對象中,并將它返回這個例子只能復(fù)制簡單的JavaBean,假定JavaBean的每個屬性都有public類型的getXXX()和setXXX()方法。第11頁JavaReflectionAPI簡介例程Re第12頁JavaReflectionAPI簡介ReflectTester類的copy(Objectobject)方法依次執(zhí)行以下步驟(1)獲得對象的類型:ClassclassType=object.getClass();System.out.println("Class:"+classType.getName());第12頁JavaReflectionAPI簡介Refl第13頁JavaReflectionAPI簡介在java.lang.Object類中定義了getClass()方法,因此對于任意一個Java對象,都可以通過此方法獲得對象的類型。Class類是ReflectionAPI中的核心類,它有以下方法getName():獲得類的完整名字。getFields():獲得類的public類型的屬性。getDeclaredFields():獲得類的所有屬性。getMethods():獲得類的public類型的方法。getDeclaredMethods():獲得類的所有方法。第13頁JavaReflectionAPI簡介在jav第14頁JavaReflectionAPI簡介getMethod(Stringname,Class[]parameterTypes):獲得類的特定方法,name參數(shù)指定方法的名字,parameterTypes參數(shù)指定方法的參數(shù)類型。getConstructors():獲得類的public類型的構(gòu)造方法。getConstructor(Class[]parameterTypes):獲得類的特定構(gòu)造方法,parameterTypes參數(shù)指定構(gòu)造方法的參數(shù)類型。newInstance():通過類的不帶參數(shù)的構(gòu)造方法創(chuàng)建這個類的一個對象。第14頁JavaReflectionAPI簡介getM第15頁JavaReflectionAPI簡介(2)通過默認構(gòu)造方法創(chuàng)建一個新對象:ObjectobjectCopy=classType.getConstructor(newClass[]{}).newInstance(newObject[]{});以上代碼先調(diào)用Class類的getConstructor()方法獲得一個Constructor對象,它代表默認的構(gòu)造方法,然后調(diào)用Constructor對象的newInstance()方法構(gòu)造一個實例。第15頁JavaReflectionAPI簡介(2)通第16頁JavaReflectionAPI簡介(3)獲得對象的所有屬性:Fieldfields[]=classType.getDeclaredFields();Class類的getDeclaredFields()方法返回類的所有屬性,包括public、protected、默認和private訪問級別的屬性第16頁JavaReflectionAPI簡介(3)獲第17頁JavaReflectionAPI簡介(4)獲得每個屬性相應(yīng)的getXXX()和setXXX()方法,然后執(zhí)行這些方法,把原來對象的屬性拷貝到新的對象中第17頁JavaReflectionAPI簡介(4)獲第18頁JavaReflectionAPI簡介在例程InvokeTester類的main()方法中,運用反射機制調(diào)用一個InvokeTester對象的add()和echo()方法第18頁JavaReflectionAPI簡介在例程I第19頁JavaReflectionAPI簡介add()方法的兩個參數(shù)為int類型,獲得表示add()方法的Method對象的代碼如下:MethodaddMethod=classType.getMethod("add",newClass[]{int.class,int.class});Method類的invoke(Objectobj,Objectargs[])方法接收的參數(shù)必須為對象,如果參數(shù)為基本類型數(shù)據(jù),必須轉(zhuǎn)換為相應(yīng)的包裝類型的對象。invoke()方法的返回值總是對象,如果實際被調(diào)用的方法的返回類型是基本類型數(shù)據(jù),那么invoke()方法會把它轉(zhuǎn)換為相應(yīng)的包裝類型的對象,再將其返回第19頁JavaReflectionAPI簡介add(第20頁JavaReflectionAPI簡介在本例中,盡管InvokeTester類的add()方法的兩個參數(shù)以及返回值都是int類型,調(diào)用addMethod對象的invoke()方法時,只能傳遞Integer類型的參數(shù),并且invoke()方法的返回類型也是Integer類型,Integer類是int基本類型的包裝類:Objectresult=addMethod.invoke(invokeTester,newObject[]{newInteger(100),newInteger(200)});System.out.println((Integer)result);//result為Integer類型第20頁JavaReflectionAPI簡介在本例中第21頁JavaReflectionAPI簡介java.lang.Array類提供了動態(tài)創(chuàng)建和訪問數(shù)組元素的各種靜態(tài)方法。例程ArrayTester1類的main()方法創(chuàng)建了一個長度為10的字符串?dāng)?shù)組,接著把索引位置為5的元素設(shè)為“hello”,然后再讀取索引位置為5的元素的值第21頁JavaReflectionAPI簡介java第22頁JavaReflectionAPI簡介例程ArrayTester2類的main()方法創(chuàng)建了一個5x10x15的整型數(shù)組,并把索引位置為[3][5][10]的元素的值為設(shè)37第22頁JavaReflectionAPI簡介例程Ar第23頁“Class” class眾所周知Java有個Objectclass,是所有Javaclasses的繼承根源,其內(nèi)聲明了數(shù)個應(yīng)該在所有Javaclass中被改寫的methods:hashCode()、equals()、clone()、toString()、getClass()等。其中g(shù)etClass()返回一個Classobject。第23頁“Class” class眾所周知Java有個O第24頁“Class” classClassclass十分特殊。它和一般classes一樣繼承自O(shè)bject,其實體用以表達Java程序運行時的classes和interfaces,也用來表達enum、array、primitiveJavatypes(boolean,byte,char,short,int,long,float,double)以及關(guān)鍵詞void。當(dāng)一個class被加載,或當(dāng)加載器(classloader)的defineClass()被JVM調(diào)用,JVM便自動產(chǎn)生一個Classobject。如果您想借由“修改Java標準庫源碼”來觀察Classobject的實際生成時機(例如在Class的constructor內(nèi)添加一個println()),不能夠!因為Class并沒有publicconstructor第24頁“Class” classClassclass第25頁“Class” classClass是Reflection起源。針對任何您想探勘的class,唯有先為它產(chǎn)生一個Classobject,接下來才能經(jīng)由后者喚起為數(shù)十多個的ReflectionAPIs第25頁“Class” classClass是Refle第26頁“Class”object的取得途徑Java允許我們從多種途徑為一個class生成對應(yīng)的Classobject第26頁“Class”object的取得途徑Java允許我第27頁“Class”object的取得途徑第27頁“Class”object的取得途徑第28頁運行時生成instances欲生成對象實體,在Reflection動態(tài)機制中有兩種作法,一個針對“無自變量ctor”,一個針對“帶參數(shù)ctor”。如果欲調(diào)用的是“帶參數(shù)ctor“就比較麻煩些,不再調(diào)用Class的newInstance(),而是調(diào)用Constructor的newInstance()。首先準備一個Class[]做為ctor的參數(shù)類型(本例指定為一個double和一個int),然后以此為自變量調(diào)用getConstructor(),獲得一個專屬ctor。接下來再準備一個Object[]做為ctor實參值(本例指定3.14159和125),調(diào)用上述專屬ctor的newInstance()。第28頁運行時生成instances欲生成對象實體,在Ref第29頁運行時生成instances動態(tài)生成“Classobject所對應(yīng)之class”的對象實體;無自變量。第29頁運行時生成instances動態(tài)生成“Classo第30頁運行時生成instances第30頁運行時生成instances第31頁運行時調(diào)用methods這個動作和上述調(diào)用“帶參數(shù)之ctor”相當(dāng)類似。首先準備一個Class[]做為參數(shù)類型(本例指定其中一個是String,另一個是Hashtable),然后以此為自變量調(diào)用getMethod(),獲得特定的Methodobject。接下來準備一個Object[]放置自變量,然后調(diào)用上述所得之特定Methodobject的invoke()。為什么獲得Methodobject時不需指定回返類型?第31頁運行時調(diào)用methods這個動作和上述調(diào)用“帶參數(shù)之第32頁運行時調(diào)用methods因為methodoverloading機制要求signature必須唯一,而回返類型并非signature的一個成份。換句話說,只要指定了method名稱和參數(shù)列,就一定指出了一個獨一無二的method。第32頁運行時調(diào)用methods因為methodoverl第33頁運行時調(diào)用methods第33頁運行時調(diào)用methods第34頁運行時變更fields內(nèi)容與先前兩個動作相比,“變更field內(nèi)容”輕松多了,因為它不需要參數(shù)和自變量。首先調(diào)用Class的getField()并指定field名稱。獲得特定的Fieldobject之后便可直接調(diào)用Field的get()和set(),第34頁運行時變更fields內(nèi)容與先前兩個動作相比,“變更第35頁運行時變更fields內(nèi)容第35頁運行時變更fields內(nèi)容第36頁目錄Java反射機制代理模式第36頁目錄Java反射機制第37頁代理模式代理模式的作用是:為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個客戶不想或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用第37頁代理模式代理模式的作用是:為其他對象提供一種代理以控第38頁代理模式代理模式一般涉及到的角色有抽象角色:聲明真實對象和代理對象的共同接口代理角色:代理對象角色內(nèi)部含有對真實對象的引用,從而可以操作真實對象,同時代理對象提供與真實對象相同的接口以便在任何時刻都能代替真實對象。同時,代理對象可以在執(zhí)行真實對象操作時,附加其他的操作,相當(dāng)于對真實對象進行封裝真實角色:代理角色所代表的真實對象,是我們最終要引用的對象第38頁代理模式代理模式一般涉及到的角色有第39頁代理模式參見程序Subject.java參見程序RealSubject.java參見程序ProxySubject.java參見程序Client.java第39頁代理模式參見程序Subject.java第40頁代理模式由以上代碼可以看出,客戶實際需要調(diào)用的是RealSubject類的request()方法,現(xiàn)在用ProxySubject來代理
RealSubject類,同樣達到目的,同時還封裝了其他方法(preRequest(),postRequest()),可以處理一些其他問題。
另外,如果要按照上述的方法使用代理模式,那么真實角色必須是事先已經(jīng)存在的,并將其作為代理對象的內(nèi)部屬性。但是實際使用時,一個真實角色必須對應(yīng)一個代理角色,如果大量使用會導(dǎo)致類的急劇膨脹;此外,如果事先并不知道真實角色,該如何使用代理呢?這個問題可以通過Java的動態(tài)代理類來解決第40頁代理模式由以上代碼可以看出,客戶實際需要調(diào)用的是Re第41頁動態(tài)代理類Java動態(tài)代理類位于java.lang.reflect包下,一般主要涉及到以下兩個類:(1)InterfaceInvocationHandler:該接口中僅定義了一個方法publicobjectinvoke(Objectobj,Methodmethod,Object[]args)在實際使用時,第一個參數(shù)obj一般是指代理類,method是被代理的方法,如上例中的request(),args為該方法的參數(shù)數(shù)組。這個抽象方法在代理類中動態(tài)實現(xiàn)。(2)Proxy:該類即為動態(tài)代理類,作用類似于上例中的ProxySubject,其中主要包含以下內(nèi)容第41頁動態(tài)代理類Java動態(tài)代理類位于java.lang第42頁動態(tài)代理類protectedProxy(InvocationHandlerh):構(gòu)造函數(shù),用于給內(nèi)部的h賦值。staticClassgetProxyClass(ClassLoaderloader,Class[]interfaces):獲得一個代理類,其中l(wèi)oader是類裝載器,interfaces是真實類所擁有的全部接口的數(shù)組。staticObjectnewProxyInstance(ClassLoaderloader,Class[]interfaces,InvocationHandlerh):返回代理類的一個實例,返回后的代理類可以當(dāng)作被代理類使用(可使用被代理類的在Subject接口中聲明過的方法)第42頁動態(tài)代理類protectedProxy(Invo第43頁動態(tài)代理類所謂DynamicProxy是這樣一種class:它是在運行時生成的class,在生成它時你必須提供一組interface給它,然后該class就宣稱它實現(xiàn)了這些interface。你當(dāng)然可以把該class的實例當(dāng)作這些interface中的任何一個來用。當(dāng)然,這個DynamicProxy其實就是一個Proxy,它不會替你作實質(zhì)性的工作,在生成它的實例時你必須提供一個handler,由它接管實際的工作第43頁動態(tài)代理類所謂DynamicProxy是這樣一種c第44頁動態(tài)代理類在使用動態(tài)代理類時,我們必須實現(xiàn)InvocationHandler接口參見程序Subject.java參見程序RealSubject.java參見程序DynamicSubject.java參見程序Client.java第44頁動態(tài)代理類在使用動態(tài)代理類時,我們必須實現(xiàn)Invoc第45頁動態(tài)代理類通過這種方式,被代理的對象(RealSubject)可以在運行時動態(tài)改變,需要控制的接口(Subject接口)可以在運行時改變,控制的方式(DynamicSubject類)也可以動態(tài)改變,從而實現(xiàn)了非常靈活的動態(tài)代理關(guān)系第45頁動態(tài)代理類通過這種方式,被代理的對象(RealSub第46頁動態(tài)代理動態(tài)代理是指客戶通過代理類來調(diào)用其它對象的方法動態(tài)代理使用場合:調(diào)試遠程方法調(diào)用(RMI)第46頁動態(tài)代理動態(tài)代理是指客戶通過代理類來調(diào)用其它對象的方第47頁動態(tài)代理客戶代理對象接口代理接口第47頁動態(tài)代理客戶接口代理接口第48頁動態(tài)代理步驟1.創(chuàng)建一個實現(xiàn)接口InvocationHandler的類,它必須實現(xiàn)invoke方法2.創(chuàng)建被代理的類以及接口3.通過Proxy的靜態(tài)方法newProxyInstance(ClassLoaderloader,Class[]interfaces,InvocationHandlerh)創(chuàng)建一個代理4.通過代理調(diào)用方法第48頁動態(tài)代理步驟1.創(chuàng)建一個實現(xiàn)接口Invocation第49頁程序?qū)嵺`參見程序VectorProxy.java參見程序Foo.java參見程序FooImpl.java參見程序FooImpl2.java參見程序CommonInvocationHandler.java參見程序Demo.java第49頁程序?qū)嵺`參見程序VectorProxy.javaJava反射機制與動態(tài)代理版權(quán)歸浪曦視頻在線所有Java反射機制與動態(tài)代理版權(quán)歸浪曦視第51頁概述本課程主要講述Java反射機制與設(shè)計模式之一:代理模式的原理與應(yīng)用同時詳細講述了Java對代理模式的支持以及Java中動態(tài)代理的原理,應(yīng)用與實踐本課程要求大家對Java泛型知識有所了解,因為程序代碼中大量使用了泛型相關(guān)知識,對于不熟悉該部分內(nèi)容的讀者,我會在下次課程中對JDK5.0中的新特性進行講解第2頁概述本課程主要講述Java反射機制與設(shè)計模式第52頁目錄Java反射機制代理模式第3頁目錄Java反射機制第53頁Java語言的反射機制在Java運行時環(huán)境中,對于任意一個類,能否知道這個類有哪些屬性和方法?對于任意一個對象,能否調(diào)用它的任意一個方法?答案是肯定的。這種動態(tài)獲取類的信息以及動態(tài)調(diào)用對象的方法的功能來自于Java語言的反射(Reflection)機制。Java反射機制主要提供了以下功能第4頁Java語言的反射機制在Java運行時環(huán)境中,對于任第54頁Java語言的反射機制在運行時判斷任意一個對象所屬的類。在運行時構(gòu)造任意一個類的對象。在運行時判斷任意一個類所具有的成員變量和方法。在運行時調(diào)用任意一個對象的方法第5頁Java語言的反射機制在運行時判斷任意一個對象所屬的第55頁Java語言的反射機制Reflection是Java被視為動態(tài)(或準動態(tài))語言的一個關(guān)鍵性質(zhì)。這個機制允許程序在運行時透過ReflectionAPIs取得任何一個已知名稱的class的內(nèi)部信息,包括其modifiers(諸如public,static等等)、superclass(例如Object)、實現(xiàn)之interfaces(例如Serializable),也包括fields和methods的所有信息,并可于運行時改變fields內(nèi)容或調(diào)用methods第6頁Java語言的反射機制Reflection是Jav第56頁Java語言的反射機制一般而言,開發(fā)者社群說到動態(tài)語言,大致認同的一個定義是:“程序運行時,允許改變程序結(jié)構(gòu)或變量類型,這種語言稱為動態(tài)語言”。從這個觀點看,Perl,Python,Ruby是動態(tài)語言,C++,Java,C#不是動態(tài)語言第7頁Java語言的反射機制一般而言,開發(fā)者社群說到動態(tài)語第57頁Java語言的反射機制盡管在這樣的定義與分類下Java不是動態(tài)語言,它卻有著一個非常突出的動態(tài)相關(guān)機制:Reflection。這個字的意思是“反射、映象、倒影”,用在Java身上指的是我們可以于運行時加載、探知、使用編譯期間完全未知的classes。換句話說,Java程序可以加載一個運行時才得知名稱的class,獲悉其完整構(gòu)造(但不包括methods定義),并生成其對象實體、或?qū)ζ鋐ields設(shè)值、或喚起其methods。這種“看透class”的能力(theabilityoftheprogramtoexamineitself)被稱為introspection(內(nèi)省、內(nèi)觀、反?。?。Reflection和introspection是常被并提的兩個術(shù)語第8頁Java語言的反射機制盡管在這樣的定義與分類下Jav第58頁JavaReflectionAPI簡介在JDK中,主要由以下類來實現(xiàn)Java反射機制,這些類都位于java.lang.reflect包中Class類:代表一個類。Field類:代表類的成員變量(成員變量也稱為類的屬性)。Method類:代表類的方法。Constructor類:代表類的構(gòu)造方法。Array類:提供了動態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組的元素的靜態(tài)方法第9頁JavaReflectionAPI簡介在JDK中第59頁JavaReflectionAPI簡介例程DumpMethods類演示了ReflectionAPI的基本作用,它讀取命令行參數(shù)指定的類名,然后打印這個類所具有的方法信息第10頁JavaReflectionAPI簡介例程Du第60頁JavaReflectionAPI簡介例程ReflectTester類進一步演示了ReflectionAPI的基本使用方法。ReflectTester類有一個copy(Objectobject)方法,這個方法能夠創(chuàng)建一個和參數(shù)object同樣類型的對象,然后把object對象中的所有屬性拷貝到新建的對象中,并將它返回這個例子只能復(fù)制簡單的JavaBean,假定JavaBean的每個屬性都有public類型的getXXX()和setXXX()方法。第11頁JavaReflectionAPI簡介例程Re第61頁JavaReflectionAPI簡介ReflectTester類的copy(Objectobject)方法依次執(zhí)行以下步驟(1)獲得對象的類型:ClassclassType=object.getClass();System.out.println("Class:"+classType.getName());第12頁JavaReflectionAPI簡介Refl第62頁JavaReflectionAPI簡介在java.lang.Object類中定義了getClass()方法,因此對于任意一個Java對象,都可以通過此方法獲得對象的類型。Class類是ReflectionAPI中的核心類,它有以下方法getName():獲得類的完整名字。getFields():獲得類的public類型的屬性。getDeclaredFields():獲得類的所有屬性。getMethods():獲得類的public類型的方法。getDeclaredMethods():獲得類的所有方法。第13頁JavaReflectionAPI簡介在jav第63頁JavaReflectionAPI簡介getMethod(Stringname,Class[]parameterTypes):獲得類的特定方法,name參數(shù)指定方法的名字,parameterTypes參數(shù)指定方法的參數(shù)類型。getConstructors():獲得類的public類型的構(gòu)造方法。getConstructor(Class[]parameterTypes):獲得類的特定構(gòu)造方法,parameterTypes參數(shù)指定構(gòu)造方法的參數(shù)類型。newInstance():通過類的不帶參數(shù)的構(gòu)造方法創(chuàng)建這個類的一個對象。第14頁JavaReflectionAPI簡介getM第64頁JavaReflectionAPI簡介(2)通過默認構(gòu)造方法創(chuàng)建一個新對象:ObjectobjectCopy=classType.getConstructor(newClass[]{}).newInstance(newObject[]{});以上代碼先調(diào)用Class類的getConstructor()方法獲得一個Constructor對象,它代表默認的構(gòu)造方法,然后調(diào)用Constructor對象的newInstance()方法構(gòu)造一個實例。第15頁JavaReflectionAPI簡介(2)通第65頁JavaReflectionAPI簡介(3)獲得對象的所有屬性:Fieldfields[]=classType.getDeclaredFields();Class類的getDeclaredFields()方法返回類的所有屬性,包括public、protected、默認和private訪問級別的屬性第16頁JavaReflectionAPI簡介(3)獲第66頁JavaReflectionAPI簡介(4)獲得每個屬性相應(yīng)的getXXX()和setXXX()方法,然后執(zhí)行這些方法,把原來對象的屬性拷貝到新的對象中第17頁JavaReflectionAPI簡介(4)獲第67頁JavaReflectionAPI簡介在例程InvokeTester類的main()方法中,運用反射機制調(diào)用一個InvokeTester對象的add()和echo()方法第18頁JavaReflectionAPI簡介在例程I第68頁JavaReflectionAPI簡介add()方法的兩個參數(shù)為int類型,獲得表示add()方法的Method對象的代碼如下:MethodaddMethod=classType.getMethod("add",newClass[]{int.class,int.class});Method類的invoke(Objectobj,Objectargs[])方法接收的參數(shù)必須為對象,如果參數(shù)為基本類型數(shù)據(jù),必須轉(zhuǎn)換為相應(yīng)的包裝類型的對象。invoke()方法的返回值總是對象,如果實際被調(diào)用的方法的返回類型是基本類型數(shù)據(jù),那么invoke()方法會把它轉(zhuǎn)換為相應(yīng)的包裝類型的對象,再將其返回第19頁JavaReflectionAPI簡介add(第69頁JavaReflectionAPI簡介在本例中,盡管InvokeTester類的add()方法的兩個參數(shù)以及返回值都是int類型,調(diào)用addMethod對象的invoke()方法時,只能傳遞Integer類型的參數(shù),并且invoke()方法的返回類型也是Integer類型,Integer類是int基本類型的包裝類:Objectresult=addMethod.invoke(invokeTester,newObject[]{newInteger(100),newInteger(200)});System.out.println((Integer)result);//result為Integer類型第20頁JavaReflectionAPI簡介在本例中第70頁JavaReflectionAPI簡介java.lang.Array類提供了動態(tài)創(chuàng)建和訪問數(shù)組元素的各種靜態(tài)方法。例程ArrayTester1類的main()方法創(chuàng)建了一個長度為10的字符串?dāng)?shù)組,接著把索引位置為5的元素設(shè)為“hello”,然后再讀取索引位置為5的元素的值第21頁JavaReflectionAPI簡介java第71頁JavaReflectionAPI簡介例程ArrayTester2類的main()方法創(chuàng)建了一個5x10x15的整型數(shù)組,并把索引位置為[3][5][10]的元素的值為設(shè)37第22頁JavaReflectionAPI簡介例程Ar第72頁“Class” class眾所周知Java有個Objectclass,是所有Javaclasses的繼承根源,其內(nèi)聲明了數(shù)個應(yīng)該在所有Javaclass中被改寫的methods:hashCode()、equals()、clone()、toString()、getClass()等。其中g(shù)etClass()返回一個Classobject。第23頁“Class” class眾所周知Java有個O第73頁“Class” classClassclass十分特殊。它和一般classes一樣繼承自O(shè)bject,其實體用以表達Java程序運行時的classes和interfaces,也用來表達enum、array、primitiveJavatypes(boolean,byte,char,short,int,long,float,double)以及關(guān)鍵詞void。當(dāng)一個class被加載,或當(dāng)加載器(classloader)的defineClass()被JVM調(diào)用,JVM便自動產(chǎn)生一個Classobject。如果您想借由“修改Java標準庫源碼”來觀察Classobject的實際生成時機(例如在Class的constructor內(nèi)添加一個println()),不能夠!因為Class并沒有publicconstructor第24頁“Class” classClassclass第74頁“Class” classClass是Reflection起源。針對任何您想探勘的class,唯有先為它產(chǎn)生一個Classobject,接下來才能經(jīng)由后者喚起為數(shù)十多個的ReflectionAPIs第25頁“Class” classClass是Refle第75頁“Class”object的取得途徑Java允許我們從多種途徑為一個class生成對應(yīng)的Classobject第26頁“Class”object的取得途徑Java允許我第76頁“Class”object的取得途徑第27頁“Class”object的取得途徑第77頁運行時生成instances欲生成對象實體,在Reflection動態(tài)機制中有兩種作法,一個針對“無自變量ctor”,一個針對“帶參數(shù)ctor”。如果欲調(diào)用的是“帶參數(shù)ctor“就比較麻煩些,不再調(diào)用Class的newInstance(),而是調(diào)用Constructor的newInstance()。首先準備一個Class[]做為ctor的參數(shù)類型(本例指定為一個double和一個int),然后以此為自變量調(diào)用getConstructor(),獲得一個專屬ctor。接下來再準備一個Object[]做為ctor實參值(本例指定3.14159和125),調(diào)用上述專屬ctor的newInstance()。第28頁運行時生成instances欲生成對象實體,在Ref第78頁運行時生成instances動態(tài)生成“Classobject所對應(yīng)之class”的對象實體;無自變量。第29頁運行時生成instances動態(tài)生成“Classo第79頁運行時生成instances第30頁運行時生成instances第80頁運行時調(diào)用methods這個動作和上述調(diào)用“帶參數(shù)之ctor”相當(dāng)類似。首先準備一個Class[]做為參數(shù)類型(本例指定其中一個是String,另一個是Hashtable),然后以此為自變量調(diào)用getMethod(),獲得特定的Methodobject。接下來準備一個Object[]放置自變量,然后調(diào)用上述所得之特定Methodobject的invoke()。為什么獲得Methodobject時不需指定回返類型?第31頁運行時調(diào)用methods這個動作和上述調(diào)用“帶參數(shù)之第81頁運行時調(diào)用methods因為methodoverloading機制要求signature必須唯一,而回返類型并非signature的一個成份。換句話說,只要指定了method名稱和參數(shù)列,就一定指出了一個獨一無二的method。第32頁運行時調(diào)用methods因為methodoverl第82頁運行時調(diào)用methods第33頁運行時調(diào)用methods第83頁運行時變更fields內(nèi)容與先前兩個動作相比,“變更field內(nèi)容”輕松多了,因為它不需要參數(shù)和自變量。首先調(diào)用Class的getField()并指定field名稱。獲得特定的Fieldobject之后便可直接調(diào)用Field的get()和set(),第34頁運行時變更fields內(nèi)容與先前兩個動作相比,“變更第84頁運行時變更fields內(nèi)容第35頁運行時變更fields內(nèi)容第85頁目錄Java反射機制代理模式第36頁目錄Java反射機制第86頁代理模式代理模式的作用是:為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個客戶不想或者不能直接引用另一個對象,而代理對象可以在客戶端和目標對象之間起到中介的作用第37頁代理模式代理模式的作用是:為其他對象提供一種代理以控第87頁代理模式代理模式一般涉及到的角色有抽象角色:聲明真實對象和代理對象的共同接口代理角色:代理對象角色內(nèi)部含有對真實對象的引用,從而可以操作真實對象,同時代理對象提供與真實對象相同的接口以便在任何時刻都能代替真實對象。同時,代理對象可以在執(zhí)行真實對象操作時,附加其他的操作,相當(dāng)于對真實對象進行封裝真實角色:代理角色所代表的真實對象,是我們最終要引用的對象第38頁代理模式代理模式一般涉及到的角色有第88頁代理模式參見程序Subject.java參見程序RealSubject.java參見程序ProxySubject.java參見程序Client.java第39頁代理模式參見程序Subject.java第89頁代理模式由以上代碼可以看出,客戶實際需要調(diào)用的是RealSubject類的request()方法,現(xiàn)在用ProxySubject來代理
RealSubject類,同樣達到目的,同時還封裝了其他方法(preRequest(),postRequest()),可以處理一些其他問題。
另外,如果要按照上述的方法使用代理模式,那么真實角色必須是事先已經(jīng)存在的,并將其作為代理對象的內(nèi)部屬性。但是實際使用時,一個真實角色
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度木材行業(yè)碳排放權(quán)交易合同8篇
- 二零二五版農(nóng)村電商合作發(fā)展合同4篇
- 二零二五年度環(huán)保設(shè)施滅四害服務(wù)合同及環(huán)保標準協(xié)議4篇
- Preparing for Pregnancy助產(chǎn)專業(yè)資源庫
- 水電安裝工程2025年度工程監(jiān)理合同2篇
- 2025版民間借貸教育基金擔(dān)保合同示例3篇
- 2025年度生態(tài)環(huán)保項目投資擔(dān)保合同書
- 2025年度離婚財產(chǎn)分割糾紛訴訟保全與執(zhí)行全程服務(wù)合同2篇
- 二零二五年度水利工程內(nèi)部施工合同4篇
- 2025年度個人別墅抵押借款合同范本5篇
- 乳腺癌的綜合治療及進展
- 【大學(xué)課件】基于BGP協(xié)議的IP黑名單分發(fā)系統(tǒng)
- 2025年八省聯(lián)考高考語文試題真題解讀及答案詳解課件
- 信息安全意識培訓(xùn)課件
- 2024年山東省泰安市初中學(xué)業(yè)水平生物試題含答案
- 美的MBS精益管理體系
- 中國高血壓防治指南(2024年修訂版)解讀課件
- 2024安全員知識考試題(全優(yōu))
- 2024年衛(wèi)生資格(中初級)-中醫(yī)外科學(xué)主治醫(yī)師考試近5年真題集錦(頻考類試題)帶答案
- 中國大百科全書(第二版全32冊)08
- 第六單元 中華民族的抗日戰(zhàn)爭 教學(xué)設(shè)計 2024-2025學(xué)年統(tǒng)編版八年級歷史上冊
評論
0/150
提交評論