java 中reflection 詳解_第1頁
java 中reflection 詳解_第2頁
java 中reflection 詳解_第3頁
java 中reflection 詳解_第4頁
java 中reflection 詳解_第5頁
已閱讀5頁,還剩45頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、浪 曦 視 頻 在 線Java反射機(jī)制與動(dòng)態(tài)代理講師:風(fēng)中葉版 權(quán) 歸 浪 曦 視 頻 在 線 所 有浪曦視頻在線http:/第第2頁頁概 述本課程主要講述Java反射機(jī)制與設(shè)計(jì)模式之一:代理模式的原理與應(yīng)用同時(shí)詳細(xì)講述了Java對代理模式的支持以及Java中動(dòng)態(tài)代理的原理,應(yīng)用與實(shí)踐本課程要求大家對Java泛型知識有所了解,因?yàn)槌绦虼a中大量使用了泛型相關(guān)知識,對于不熟悉該部分內(nèi)容的讀者,我會在下次課程中對JDK5.0中的新特性進(jìn)行講解浪曦視頻在線http:/第第3頁頁目錄JavaJava反射機(jī)制反射機(jī)制代理模式代理模式浪曦視頻在線http:/第第4頁頁Java 語言的反射機(jī)制在在JavaJ

2、ava運(yùn)行時(shí)運(yùn)行時(shí)環(huán)境中,對于任意一個(gè)類,能否知道這個(gè)類環(huán)境中,對于任意一個(gè)類,能否知道這個(gè)類有哪些屬性和方法?對于任意一個(gè)對象,能否調(diào)用它的任有哪些屬性和方法?對于任意一個(gè)對象,能否調(diào)用它的任意一個(gè)方法?答案是意一個(gè)方法?答案是肯定肯定的。這種動(dòng)態(tài)獲取類的信息以及的。這種動(dòng)態(tài)獲取類的信息以及動(dòng)態(tài)調(diào)用對象的方法的功能來自于動(dòng)態(tài)調(diào)用對象的方法的功能來自于Java Java 語言的反射語言的反射(ReflectionReflection)機(jī)制。)機(jī)制。Java Java 反射機(jī)制主要提供了以下功能反射機(jī)制主要提供了以下功能浪曦視頻在線http:/第第5頁頁Java 語言的反射機(jī)制在運(yùn)行時(shí)判斷任意一

3、個(gè)對象所屬的類。在運(yùn)行時(shí)判斷任意一個(gè)對象所屬的類。在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對象。在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對象。在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法。在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法。在運(yùn)行時(shí)調(diào)用任意一個(gè)對象的方法在運(yùn)行時(shí)調(diào)用任意一個(gè)對象的方法浪曦視頻在線http:/第第6頁頁Java 語言的反射機(jī)制Reflection Reflection 是是JavaJava被視為動(dòng)態(tài)(或準(zhǔn)動(dòng)態(tài))語言的一個(gè)被視為動(dòng)態(tài)(或準(zhǔn)動(dòng)態(tài))語言的一個(gè)關(guān)鍵性質(zhì)。這個(gè)機(jī)制允許程序在運(yùn)行時(shí)透過關(guān)鍵性質(zhì)。這個(gè)機(jī)制允許程序在運(yùn)行時(shí)透過Reflection Reflection APIsAPIs取得任何一個(gè)取得

4、任何一個(gè)已知名稱已知名稱的的classclass的內(nèi)部信息,包括其的內(nèi)部信息,包括其modifiersmodifiers(諸如(諸如public, static public, static 等等)、等等)、superclasssuperclass(例如(例如ObjectObject)、實(shí)現(xiàn)之)、實(shí)現(xiàn)之interfacesinterfaces(例如(例如SerializableSerializable),也包括),也包括fieldsfields和和methodsmethods的所有信息,的所有信息,并可于運(yùn)行時(shí)改變并可于運(yùn)行時(shí)改變fieldsfields內(nèi)容或調(diào)用內(nèi)容或調(diào)用methodsmet

5、hods浪曦視頻在線http:/第第7頁頁Java 語言的反射機(jī)制一般而言,開發(fā)者社群說到動(dòng)態(tài)語言,大致認(rèn)同的一個(gè)定一般而言,開發(fā)者社群說到動(dòng)態(tài)語言,大致認(rèn)同的一個(gè)定義是:義是:“程序運(yùn)行時(shí),允許改變程序結(jié)構(gòu)或變量類型,這程序運(yùn)行時(shí),允許改變程序結(jié)構(gòu)或變量類型,這種語言稱為動(dòng)態(tài)語言種語言稱為動(dòng)態(tài)語言”。從這個(gè)觀點(diǎn)看,。從這個(gè)觀點(diǎn)看,PerlPerl,PythonPython,RubyRuby是動(dòng)態(tài)語言,是動(dòng)態(tài)語言,C+C+,JavaJava,C#C#不是動(dòng)態(tài)語言不是動(dòng)態(tài)語言浪曦視頻在線http:/第第8頁頁Java 語言的反射機(jī)制盡管在這樣的定義與分類下盡管在這樣的定義與分類下JavaJava

6、不是動(dòng)態(tài)語言,它卻有著不是動(dòng)態(tài)語言,它卻有著一個(gè)非常突出的動(dòng)態(tài)相關(guān)機(jī)制:一個(gè)非常突出的動(dòng)態(tài)相關(guān)機(jī)制:ReflectionReflection。這個(gè)字的意。這個(gè)字的意思是思是“反射、映象、倒影反射、映象、倒影”,用在,用在JavaJava身上指的是我們可身上指的是我們可以于運(yùn)行時(shí)加載、探知、使用編譯期間完全未知的以于運(yùn)行時(shí)加載、探知、使用編譯期間完全未知的classesclasses。換句話說,。換句話說,JavaJava程序可以加載一個(gè)運(yùn)行時(shí)才得程序可以加載一個(gè)運(yùn)行時(shí)才得知名稱的知名稱的classclass,獲悉其完整構(gòu)造(,獲悉其完整構(gòu)造(但不包括但不包括methodsmethods定定義義

7、),并生成其對象實(shí)體、或?qū)ζ洌?,并生成其對象?shí)體、或?qū)ζ鋐ieldsfields設(shè)值、或喚起其設(shè)值、或喚起其methodsmethods。這種。這種“看透看透class”class”的能力(的能力(the ability of the ability of the program to examine itselfthe program to examine itself)被稱為)被稱為introspectionintrospection(內(nèi)省、內(nèi)觀、反?。?。(內(nèi)省、內(nèi)觀、反?。?。ReflectionReflection和和introspectionintrospection是是常被并提的兩個(gè)

8、術(shù)語常被并提的兩個(gè)術(shù)語浪曦視頻在線http:/第第9頁頁Java Reflection API 簡介在在JDKJDK中,主要由以下類來實(shí)現(xiàn)中,主要由以下類來實(shí)現(xiàn)JavaJava反射機(jī)制,這些類都反射機(jī)制,這些類都位于位于java.lang.reflectjava.lang.reflect包中包中Class類:代表一個(gè)類。Field 類:代表類的成員變量(成員變量也稱為類的屬性)。Method類:代表類的方法。Constructor 類:代表類的構(gòu)造方法。Array類:提供了動(dòng)態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組的元素的靜態(tài)方法浪曦視頻在線http:/第第10頁頁Java Reflection API 簡介

9、例程例程DumpMethodsDumpMethods類演示了類演示了Reflection APIReflection API的基本作用,的基本作用,它讀取命令行參數(shù)指定的類名,然后打印這個(gè)類所具有的它讀取命令行參數(shù)指定的類名,然后打印這個(gè)類所具有的方法信息方法信息浪曦視頻在線http:/第第11頁頁Java Reflection API 簡介例程例程ReflectTester ReflectTester 類進(jìn)一步演示了類進(jìn)一步演示了Reflection APIReflection API的基的基本使用方法。本使用方法。ReflectTesterReflectTester類有一個(gè)類有一個(gè)copy

10、(Object copy(Object object)object)方法,這個(gè)方法能夠創(chuàng)建一個(gè)和參數(shù)方法,這個(gè)方法能夠創(chuàng)建一個(gè)和參數(shù)object object 同樣同樣類型的對象,然后把類型的對象,然后把objectobject對象中的所有屬性拷貝到新建對象中的所有屬性拷貝到新建的對象中,并將它返回的對象中,并將它返回這個(gè)例子只能復(fù)制簡單的這個(gè)例子只能復(fù)制簡單的JavaBeanJavaBean,假定,假定JavaBean JavaBean 的每的每個(gè)屬性都有個(gè)屬性都有public public 類型的類型的getXXX()getXXX()和和setXXX()setXXX()方法。方法。浪曦視頻

11、在線http:/第第12頁頁Java Reflection API 簡介ReflectTester ReflectTester 類的類的copy(Object object)copy(Object object)方法依次執(zhí)行方法依次執(zhí)行以下步驟以下步驟(1 1)獲得對象的類型:)獲得對象的類型:Class classType=object.getClass();System.out.println(Class:+classType.getName();浪曦視頻在線http:/第第13頁頁Java Reflection API 簡介在在java.lang.Object java.lang.Obj

12、ect 類中定義了類中定義了getClass()getClass()方法,因此方法,因此對于任意一個(gè)對于任意一個(gè)JavaJava對象,都可以通過此方法獲得對象的類對象,都可以通過此方法獲得對象的類型。型。ClassClass類是類是Reflection API Reflection API 中的核心類,它有以下方中的核心類,它有以下方法法getName():獲得類的完整名字。getFields():獲得類的public類型的屬性。getDeclaredFields():獲得類的所有屬性。getMethods():獲得類的public類型的方法。getDeclaredMethods():獲得類的

13、所有方法。浪曦視頻在線http:/第第14頁頁Java Reflection API 簡介getMethod(String name, Class parameterTypes)getMethod(String name, Class parameterTypes):獲:獲得類的特定方法,得類的特定方法,namename參數(shù)指定方法的名字,參數(shù)指定方法的名字,parameterTypes parameterTypes 參數(shù)指定方法的參數(shù)類型。參數(shù)指定方法的參數(shù)類型。getConstructors()getConstructors():獲得類的:獲得類的publicpublic類型的構(gòu)造方法。類

14、型的構(gòu)造方法。getConstructor(Class parameterTypes)getConstructor(Class parameterTypes):獲得類的特:獲得類的特定構(gòu)造方法,定構(gòu)造方法,parameterTypes parameterTypes 參數(shù)指定構(gòu)造方法的參數(shù)參數(shù)指定構(gòu)造方法的參數(shù)類型。類型。newInstance()newInstance():通過類的:通過類的不帶參數(shù)不帶參數(shù)的構(gòu)造方法創(chuàng)建這個(gè)的構(gòu)造方法創(chuàng)建這個(gè)類的一個(gè)對象。類的一個(gè)對象。浪曦視頻在線http:/第第15頁頁Java Reflection API 簡介(2 2)通過默認(rèn)構(gòu)造方法創(chuàng)建一個(gè)新對象:)通

15、過默認(rèn)構(gòu)造方法創(chuàng)建一個(gè)新對象:Object objectCopy=classType.getConstructor(new Object objectCopy=classType.getConstructor(new Class).newInstance(new Object);Class).newInstance(new Object);以上代碼先調(diào)用以上代碼先調(diào)用ClassClass類的類的getConstructor()getConstructor()方法獲得一個(gè)方法獲得一個(gè)Constructor Constructor 對象,對象,它代表默認(rèn)的構(gòu)造方法它代表默認(rèn)的構(gòu)造方法,然后調(diào)用,然

16、后調(diào)用ConstructorConstructor對象的對象的newInstance()newInstance()方法構(gòu)造一個(gè)實(shí)例。方法構(gòu)造一個(gè)實(shí)例。浪曦視頻在線http:/第第16頁頁Java Reflection API 簡介(3 3)獲得對象的所有屬性:)獲得對象的所有屬性:Field fields=classType.getDeclaredFields();Field fields=classType.getDeclaredFields();Class Class 類的類的getDeclaredFields()getDeclaredFields()方法返回類的所有屬性,包括方法返回類的

17、所有屬性,包括publicpublic、protectedprotected、默認(rèn)和、默認(rèn)和privateprivate訪問級別的屬性訪問級別的屬性浪曦視頻在線http:/第第17頁頁Java Reflection API 簡介(4 4)獲得每個(gè)屬性相應(yīng)的)獲得每個(gè)屬性相應(yīng)的getXXX()getXXX()和和setXXX()setXXX()方法,然后執(zhí)行這些方法,然后執(zhí)行這些方法,把原來對象的屬性拷貝到新的對象中方法,把原來對象的屬性拷貝到新的對象中浪曦視頻在線http:/第第18頁頁Java Reflection API 簡介在例程在例程InvokeTesterInvokeTester類的

18、類的main()main()方法中,運(yùn)用反射機(jī)制調(diào)用一個(gè)方法中,運(yùn)用反射機(jī)制調(diào)用一個(gè)InvokeTesterInvokeTester對象的對象的add()add()和和echo()echo()方法方法浪曦視頻在線http:/第第19頁頁Java Reflection API 簡介add()add()方法的兩個(gè)參數(shù)為方法的兩個(gè)參數(shù)為int int 類型,獲得表示類型,獲得表示add()add()方法的方法的MethodMethod對象的代碼如下:對象的代碼如下:Method addMethod=classType.getMethod(add,new Method addMethod=classT

19、ype.getMethod(add,new Classint.class,int.class);Classint.class,int.class);MethodMethod類的類的invoke(Object obj,Object args)invoke(Object obj,Object args)方法方法接收接收的參數(shù)必須為對象的參數(shù)必須為對象,如果參數(shù)為基本類型數(shù)據(jù),必須轉(zhuǎn)換,如果參數(shù)為基本類型數(shù)據(jù),必須轉(zhuǎn)換為相應(yīng)的包裝類型的對象。為相應(yīng)的包裝類型的對象。invoke()invoke()方法的返回值總是對方法的返回值總是對象象,如果實(shí)際被調(diào)用的方法的返回類型是基本類型數(shù)據(jù),如果實(shí)際被調(diào)用的

20、方法的返回類型是基本類型數(shù)據(jù),那么那么invoke()invoke()方法會把它轉(zhuǎn)換為相應(yīng)的包裝類型的對象,方法會把它轉(zhuǎn)換為相應(yīng)的包裝類型的對象,再將其返回再將其返回浪曦視頻在線http:/第第20頁頁Java Reflection API 簡介在本例中,盡管在本例中,盡管InvokeTester InvokeTester 類的類的add()add()方法的兩個(gè)參數(shù)方法的兩個(gè)參數(shù)以及返回值都是以及返回值都是intint類型,調(diào)用類型,調(diào)用add Method add Method 對象的對象的invoke()invoke()方法時(shí),只能傳遞方法時(shí),只能傳遞Integer Integer 類型的

21、參數(shù),并且類型的參數(shù),并且invoke()invoke()方法的返回類型也是方法的返回類型也是Integer Integer 類型,類型,Integer Integer 類類是是int int 基本類型的包裝類:基本類型的包裝類:Object result=addMethod.invoke(invokeTester,Object result=addMethod.invoke(invokeTester,new Objectnew Integer(100),new Integer(200);new Objectnew Integer(100),new Integer(200);System.ou

22、t.println(System.out.println(Integer)result(Integer)result); /result ); /result 為為IntegerInteger類型類型浪曦視頻在線http:/第第21頁頁Java Reflection API 簡介java.lang.Array java.lang.Array 類提供了動(dòng)態(tài)創(chuàng)建和訪問數(shù)組元素的各種類提供了動(dòng)態(tài)創(chuàng)建和訪問數(shù)組元素的各種靜態(tài)靜態(tài)方法。方法。例程例程ArrayTester1 ArrayTester1 類的類的main()main()方法創(chuàng)建了一個(gè)長度為方法創(chuàng)建了一個(gè)長度為10 10 的字符串?dāng)?shù)組,的字符

23、串?dāng)?shù)組,接著把索引位置為接著把索引位置為5 5 的元素設(shè)為的元素設(shè)為“hello”hello”,然后再讀取索引位置為,然后再讀取索引位置為5 5 的元素的值的元素的值浪曦視頻在線http:/第第22頁頁Java Reflection API 簡介例程例程ArrayTester2 ArrayTester2 類的類的main()main()方法創(chuàng)建了一個(gè)方法創(chuàng)建了一個(gè) 5 x 10 x 15 5 x 10 x 15 的整型的整型數(shù)組,并把索引位置為數(shù)組,并把索引位置為3510 3510 的元素的值為設(shè)的元素的值為設(shè)3737浪曦視頻在線http:/第第23頁頁“Class” class眾所周知眾所周

24、知JavaJava有個(gè)有個(gè)Object classObject class,是所有,是所有Java classesJava classes的繼承根源,的繼承根源,其內(nèi)聲明了數(shù)個(gè)應(yīng)該在所有其內(nèi)聲明了數(shù)個(gè)應(yīng)該在所有Java classJava class中被改寫的中被改寫的methodsmethods:hashCode()hashCode()、equals()equals()、clone()clone()、toString()toString()、getClass()getClass()等。其等。其中中g(shù)etClass()getClass()返回一個(gè)返回一個(gè)Class objectClass ob

25、ject。浪曦視頻在線http:/第第24頁頁“Class” classClass classClass class十分特殊。它和一般十分特殊。它和一般classesclasses一樣繼承自一樣繼承自O(shè)bjectObject,其實(shí)體用以表達(dá),其實(shí)體用以表達(dá)JavaJava程序運(yùn)行時(shí)的程序運(yùn)行時(shí)的classesclasses和和interfacesinterfaces,也用來表達(dá),也用來表達(dá)enumenum、arrayarray、primitive Java primitive Java typestypes(boolean, byte, char, short, int, long, floa

26、t, boolean, byte, char, short, int, long, float, doubledouble)以及關(guān)鍵詞)以及關(guān)鍵詞voidvoid。當(dāng)一個(gè)。當(dāng)一個(gè)classclass被加載,或當(dāng)加被加載,或當(dāng)加載器(載器(class loaderclass loader)的)的defineClass()defineClass()被被JVMJVM調(diào)用,調(diào)用,JVM JVM 便自動(dòng)產(chǎn)生一個(gè)便自動(dòng)產(chǎn)生一個(gè)Class objectClass object。如果您想借由。如果您想借由“修改修改JavaJava標(biāo)準(zhǔn)庫源碼標(biāo)準(zhǔn)庫源碼”來觀察來觀察Class objectClass objec

27、t的實(shí)際生成時(shí)機(jī)(例如的實(shí)際生成時(shí)機(jī)(例如在在ClassClass的的constructorconstructor內(nèi)添加一個(gè)內(nèi)添加一個(gè)println()println()),),不能夠不能夠!因?yàn)橐驗(yàn)镃lassClass并沒有并沒有public constructorpublic constructor浪曦視頻在線http:/第第25頁頁“Class” classClassClass是是ReflectionReflection起源。針對任何您想探勘的起源。針對任何您想探勘的classclass,唯有先為它產(chǎn),唯有先為它產(chǎn)生一個(gè)生一個(gè)Class objectClass object,接下來才能經(jīng)

28、由后者喚起為數(shù)十多個(gè)的,接下來才能經(jīng)由后者喚起為數(shù)十多個(gè)的Reflection APIsReflection APIs浪曦視頻在線http:/第第26頁頁“Class” object的取得途徑JavaJava允許我們從多種途徑為一個(gè)允許我們從多種途徑為一個(gè)classclass生成對應(yīng)的生成對應(yīng)的Class objectClass object浪曦視頻在線http:/第第27頁頁“Class” object的取得途徑浪曦視頻在線http:/第第28頁頁運(yùn)行時(shí)生成instances欲生成對象實(shí)體,在欲生成對象實(shí)體,在Reflection Reflection 動(dòng)態(tài)機(jī)制中有兩種作法,一個(gè)針對動(dòng)態(tài)機(jī)制

29、中有兩種作法,一個(gè)針對“無自變量無自變量ctor”ctor”,一個(gè)針對,一個(gè)針對“帶參數(shù)帶參數(shù)ctor”ctor”。如果欲調(diào)用的是。如果欲調(diào)用的是“帶帶參數(shù)參數(shù)ctor“ctor“就比較麻煩些,不再調(diào)用就比較麻煩些,不再調(diào)用ClassClass的的newInstance()newInstance(),而是調(diào),而是調(diào)用用Constructor Constructor 的的newInstance()newInstance()。首先準(zhǔn)備一個(gè)。首先準(zhǔn)備一個(gè)ClassClass做為做為ctorctor的的參數(shù)類型(本例指定參數(shù)類型(本例指定為一個(gè)為一個(gè)doubledouble和一個(gè)和一個(gè)intint),

30、然后以此為自變量調(diào)用),然后以此為自變量調(diào)用getConstructor()getConstructor(),獲得一個(gè)專屬,獲得一個(gè)專屬ctorctor。接下來再準(zhǔn)備一個(gè)。接下來再準(zhǔn)備一個(gè)Object Object 做為做為ctorctor實(shí)參值(本例指定實(shí)參值(本例指定3.141593.14159和和125125),調(diào)用上述專屬),調(diào)用上述專屬ctorctor的的newInstance()newInstance()。浪曦視頻在線http:/第第29頁頁運(yùn)行時(shí)生成instances動(dòng)態(tài)生成“Class object 所對應(yīng)之class”的對象實(shí)體;無自變量。浪曦視頻在線http:/第第30頁頁

31、運(yùn)行時(shí)生成instances浪曦視頻在線http:/第第31頁頁運(yùn)行時(shí)調(diào)用methods這個(gè)動(dòng)作和上述調(diào)用這個(gè)動(dòng)作和上述調(diào)用“帶參數(shù)之帶參數(shù)之ctor”ctor”相當(dāng)類似。首先準(zhǔn)備一個(gè)相當(dāng)類似。首先準(zhǔn)備一個(gè)ClassClass做做為參數(shù)類型(本例指定其中一個(gè)是為參數(shù)類型(本例指定其中一個(gè)是StringString,另一個(gè)是,另一個(gè)是HashtableHashtable),然后以),然后以此為自變量調(diào)用此為自變量調(diào)用getMethod()getMethod(),獲得特定的,獲得特定的Method objectMethod object。接下來準(zhǔn)備一個(gè)。接下來準(zhǔn)備一個(gè)ObjectObject放置自

32、變量,然后調(diào)用上述所得之特定放置自變量,然后調(diào)用上述所得之特定Method objectMethod object的的invoke()invoke()。為什么獲得為什么獲得Method objectMethod object時(shí)不需指定回返類型?時(shí)不需指定回返類型?浪曦視頻在線http:/第第32頁頁運(yùn)行時(shí)調(diào)用methods因?yàn)橐驗(yàn)閙ethod overloadingmethod overloading機(jī)制要求機(jī)制要求signaturesignature必須唯一,而回返類型必須唯一,而回返類型并非并非signaturesignature的一個(gè)成份。換句話說,只要指定了的一個(gè)成份。換句話說,只要指

33、定了methodmethod名稱和參名稱和參數(shù)列,就一定指出了一個(gè)獨(dú)一無二的數(shù)列,就一定指出了一個(gè)獨(dú)一無二的methodmethod。浪曦視頻在線http:/第第33頁頁運(yùn)行時(shí)調(diào)用methods浪曦視頻在線http:/第第34頁頁運(yùn)行時(shí)變更fields內(nèi)容與先前兩個(gè)動(dòng)作相比,與先前兩個(gè)動(dòng)作相比,“變更變更fieldfield內(nèi)容內(nèi)容”輕松多了,因?yàn)樗恍枰p松多了,因?yàn)樗恍枰獏?shù)和自變量。首先調(diào)用參數(shù)和自變量。首先調(diào)用ClassClass的的getField()getField()并指定并指定fieldfield名稱。獲得名稱。獲得特定的特定的Field objectField object

34、之后便可直接調(diào)用之后便可直接調(diào)用FieldField的的get()get()和和set()set(),浪曦視頻在線http:/第第35頁頁運(yùn)行時(shí)變更fields內(nèi)容浪曦視頻在線http:/第第36頁頁目錄JavaJava反射機(jī)制反射機(jī)制代理模式代理模式浪曦視頻在線http:/第第37頁頁代理模式代理模式的作用是:為其他對象提供一種代理以控制對這個(gè)對象的訪代理模式的作用是:為其他對象提供一種代理以控制對這個(gè)對象的訪問。問。在某些情況下,一個(gè)客戶不想或者不能直接引用另一個(gè)對象,而代理在某些情況下,一個(gè)客戶不想或者不能直接引用另一個(gè)對象,而代理對象可以在客戶端和目標(biāo)對象之間起到對象可以在客戶端和目標(biāo)

35、對象之間起到中介中介的作用的作用浪曦視頻在線http:/第第38頁頁代理模式代理模式一般涉及到的角色有代理模式一般涉及到的角色有 抽象角色:聲明真實(shí)對象和代理對象的共同接口代理角色:代理對象角色內(nèi)部含有對真實(shí)對象的引用,從而可以操作真實(shí)對象,同時(shí)代理對象提供與真實(shí)對象相同的接口以便在任何時(shí)刻都能代替真實(shí)對象。同時(shí),代理對象可以在執(zhí)行真實(shí)對象操作時(shí),附加其他的操作,相當(dāng)于對真實(shí)對象進(jìn)行封裝真實(shí)角色:代理角色所代表的真實(shí)對象,是我們最終要引用的對象浪曦視頻在線http:/第第39頁頁代理模式參見程序參見程序Subject.javaSubject.java參見程序參見程序RealSubject.ja

36、vaRealSubject.java參見程序參見程序ProxySubject.javaProxySubject.java參見程序參見程序Client.javaClient.java浪曦視頻在線http:/第第40頁頁代理模式由以上代碼可以看出,客戶實(shí)際需要調(diào)用的是由以上代碼可以看出,客戶實(shí)際需要調(diào)用的是RealSubjectRealSubject類的類的request()request()方法,現(xiàn)在用方法,現(xiàn)在用ProxySubjectProxySubject來來代理代理 RealSubjectRealSubject類,同樣達(dá)到目的,同時(shí)還封裝了其他類,同樣達(dá)到目的,同時(shí)還封裝了其他方法方法(

37、preRequest(),postRequest()(preRequest(),postRequest(),可以處理一些其他,可以處理一些其他問題。問題。 另外,另外,如果要按照上述的方法使用代理模式,那么真實(shí)角如果要按照上述的方法使用代理模式,那么真實(shí)角色必須是事先已經(jīng)存在的,并將其作為代理對象的內(nèi)部屬色必須是事先已經(jīng)存在的,并將其作為代理對象的內(nèi)部屬性性。但是實(shí)際使用時(shí),一個(gè)真實(shí)角色必須對應(yīng)一個(gè)。但是實(shí)際使用時(shí),一個(gè)真實(shí)角色必須對應(yīng)一個(gè) 代理代理角色,如果大量使用會導(dǎo)致類的急劇膨脹;此外,如果事角色,如果大量使用會導(dǎo)致類的急劇膨脹;此外,如果事先并不知道真實(shí)角色,該如何使用代理呢?這個(gè)問題

38、可以先并不知道真實(shí)角色,該如何使用代理呢?這個(gè)問題可以通過通過JavaJava的的動(dòng)態(tài)代理類動(dòng)態(tài)代理類來解決來解決浪曦視頻在線http:/第第41頁頁動(dòng)態(tài)代理類 JavaJava動(dòng)態(tài)代理類位于動(dòng)態(tài)代理類位于java.lang.reflectjava.lang.reflect包下,一般主要涉及到以下包下,一般主要涉及到以下兩個(gè)類:兩個(gè)類: (1)Interface InvocationHandler(1)Interface InvocationHandler:該接口中僅定義了一個(gè)方法:該接口中僅定義了一個(gè)方法public object invoke(Object obj,Method metho

39、d, Object args)在實(shí)際使用時(shí),在實(shí)際使用時(shí),第一個(gè)參數(shù)第一個(gè)參數(shù)objobj一般是指代理類,一般是指代理類,methodmethod是被代理的是被代理的方法,如上例中的方法,如上例中的request()request(),argsargs為該方法的參數(shù)數(shù)組為該方法的參數(shù)數(shù)組。 這個(gè)抽象這個(gè)抽象方法在代理類中動(dòng)態(tài)實(shí)現(xiàn)。方法在代理類中動(dòng)態(tài)實(shí)現(xiàn)。 (2)Proxy(2)Proxy:該類即為動(dòng)態(tài)代理類該類即為動(dòng)態(tài)代理類,作用類似于上例中的,作用類似于上例中的ProxySubjectProxySubject,其中主要包含以下內(nèi)容其中主要包含以下內(nèi)容浪曦視頻在線http:/第第42頁頁動(dòng)態(tài)代

40、理類 protected Proxy(InvocationHandler h)protected Proxy(InvocationHandler h):構(gòu)造函數(shù),用于給內(nèi)部的:構(gòu)造函數(shù),用于給內(nèi)部的h h賦值。賦值。 static Class getProxyClass (ClassLoader loader, Class static Class getProxyClass (ClassLoader loader, Class interfaces)interfaces):獲得一個(gè)代理類,其中:獲得一個(gè)代理類,其中l(wèi)oaderloader是類裝載器,是類裝載器,interfacesinter

41、faces是真實(shí)類所擁有的全部接口的數(shù)組。是真實(shí)類所擁有的全部接口的數(shù)組。 static Object newProxyInstance(ClassLoader loader, Class static Object newProxyInstance(ClassLoader loader, Class interfaces, InvocationHandler h)interfaces, InvocationHandler h):返回代理類的一個(gè)實(shí)例返回代理類的一個(gè)實(shí)例,返回,返回后的代理類可以當(dāng)作被代理類使用后的代理類可以當(dāng)作被代理類使用( (可使用被代理類的在可使用被代理類的在Subjec

42、tSubject接口接口中聲明過的方法中聲明過的方法) )浪曦視頻在線http:/第第43頁頁動(dòng)態(tài)代理類所謂所謂Dynamic ProxyDynamic Proxy是這樣一種是這樣一種classclass:它是在運(yùn)行時(shí)生成的:它是在運(yùn)行時(shí)生成的classclass,在生成它時(shí)你必須提供一組在生成它時(shí)你必須提供一組interfaceinterface給它,然后該給它,然后該classclass就宣稱它實(shí)就宣稱它實(shí)現(xiàn)了這些現(xiàn)了這些 interfaceinterface。你當(dāng)然可以把該。你當(dāng)然可以把該classclass的實(shí)例當(dāng)作這些的實(shí)例當(dāng)作這些interfaceinterface中的任何一個(gè)來用。當(dāng)然,這個(gè)中的任何一個(gè)來用。當(dāng)然,這個(gè)Dyn

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論