




已閱讀5頁(yè),還剩17頁(yè)未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
反射學(xué)習(xí)整理【摘要】本文主要通過(guò)自己對(duì)反射機(jī)制的總結(jié)編寫(xiě)的文檔,主要目的就是為了自己以后能可以參考溫習(xí)也可以方便剛剛?cè)腴T(mén)的同仁們學(xué)習(xí)指導(dǎo),通過(guò)doc的編寫(xiě)相信可以在幫助別人的同時(shí)提高自己。 反射機(jī)制; Reflection API; 如何使用反射機(jī)制; 反射機(jī)制的應(yīng)用舉例;第一節(jié) 反射機(jī)制什么是反射機(jī)制,說(shuō)的通俗一些就是在java運(yùn)行期間動(dòng)態(tài)加載一些不確定的類(lèi)對(duì)象,那么我們?nèi)绾问褂靡粋€(gè)類(lèi)的呢?當(dāng)然大多數(shù)情況下我們是使用一個(gè)確定的類(lèi),然后通過(guò)在內(nèi)存中的加載再使用之。其實(shí)在一個(gè)project中會(huì)有很多類(lèi),虛擬機(jī)并不是在每一次運(yùn)行時(shí)都將所有的類(lèi)都進(jìn)行加載然后解析的,是在我們使用的過(guò)程中才會(huì)被加載,這個(gè)大家可以看一下ClassLoader(在后期中我也會(huì)編寫(xiě)ClassLoader相關(guān)的文章總結(jié))反射機(jī)制提供的功能: 加載運(yùn)行時(shí)才能確定的數(shù)據(jù)類(lèi)型; 解析類(lèi)的結(jié)構(gòu),獲取其內(nèi)部的信息; 能夠操作的類(lèi)型或者實(shí)例;1. 訪問(wèn)屬性;2. 調(diào)用方法;3. 創(chuàng)建新的對(duì)象;以上的功能我會(huì)在接下來(lái)的文字中都進(jìn)行闡述,然后每一個(gè)功能點(diǎn)都會(huì)通過(guò)代碼的形式進(jìn)行逐一的說(shuō)明舉例;1.1動(dòng)態(tài)加載類(lèi)Java虛擬機(jī)在運(yùn)行是能加載的類(lèi)型有如下幾種: 類(lèi)接口; 數(shù)組; 枚舉; 注解(Annotation,可以參見(jiàn)我的另一篇文檔,java Annotation學(xué)習(xí)文檔); 基本數(shù)據(jù)類(lèi)型;在類(lèi)加載的時(shí)候,JVM會(huì)自動(dòng)加載上述類(lèi)型對(duì)應(yīng)的Class對(duì)象。package com.wangwenjun.demo;import java.util.ArrayList;public class ReflectionDemo1 private final static String LIST_STRING=java.util.ArrayList;/動(dòng)態(tài)加載java.util.ArrayList的類(lèi)路徑SuppressWarnings(unchecked)public static void main(String args) try Class clazz=Class.forName(LIST_STRING);/通過(guò)反射獲取運(yùn)行時(shí)的ClassArrayList list=(ArrayList) clazz.newInstance(); /通過(guò)newInstance方法獲取Objectlist.add(hello);System.out.println(list.size()+:+list.get(0); catch (ClassNotFoundException e) e.printStackTrace(); catch (InstantiationException e) / TODO Auto-generated catch blocke.printStackTrace(); catch (IllegalAccessException e) / TODO Auto-generated catch blocke.printStackTrace();執(zhí)行結(jié)果為:1:hello通過(guò)上面的代碼我們可以總結(jié)出來(lái)使用Reflection大致需要如下的幾步: 獲取目標(biāo)對(duì)象的Class對(duì)象; 調(diào)用Class對(duì)象內(nèi)省方法獲取目標(biāo)對(duì)類(lèi)成員信息; 訪問(wèn)目標(biāo)類(lèi)的成員屬性;1.2解析類(lèi)的結(jié)構(gòu)通過(guò)第一步的操作,我們獲取了目標(biāo)對(duì)象的class之后就可以解析出來(lái)class對(duì)應(yīng)的內(nèi)部結(jié)構(gòu);別不多說(shuō)直接上代碼,來(lái)看看如何解析出來(lái)目標(biāo)對(duì)象;我們定義一個(gè)Teacher類(lèi)package com.wangwenjun.demo;public class Teacher private String username;private int age;private static int total;public Teacher()super();total+;public Teacher(String username,int age)super();this.username = username;this.age = age;total+;public String getUsername() return username;public void setUsername(String username) this.username = username;public int getAge() return age;public void setAge(int age) this.age = age;public static int getTotal() return total;public static void setTotal(int total) Teacher.total = total;Overridepublic String toString()return UserName:+this.username+,age:+this.age;假如說(shuō)上述的Teacher類(lèi)是在我們運(yùn)行時(shí)才知道的一個(gè)類(lèi),也就是說(shuō)是我們運(yùn)行時(shí)才能確定的一個(gè)類(lèi),那么我們就可以通過(guò)反射的形式將它解析出來(lái),包括它的屬性,方法,以及構(gòu)造函數(shù)等等。好了,下面有一個(gè)專(zhuān)門(mén)的類(lèi)針對(duì)Teacher進(jìn)行解析,通過(guò)觀察打印的語(yǔ)句我們就可以看出來(lái)效果package com.wangwenjun.demo;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;public class ReflectionTeacher private final static String TEACHER_CLASS=com.wangwenjun.demo.Teacher;SuppressWarnings(unchecked)public static void main(String args) try Class clazz = Class.forName(TEACHER_CLASS);Field fields = clazz.getDeclaredFields(); /獲取該類(lèi)中的屬性成員Method methods = clazz.getDeclaredMethods();/獲取該類(lèi)中的成員方法Constructor constructors = clazz.getConstructors();/獲取該類(lèi)的所有構(gòu)造方法System.out.println(*打印成員屬性*);for(Field field:fields)System.out.println(屬性:+field);System.out.println(名稱:+field.getName();System.out.println(修飾符:+Modifier.toString(field.getModifiers();System.out.println(數(shù)據(jù)類(lèi)型:+field.getType();System.out.println(=);System.out.println(*打印成員方法*);for(Method method:methods)System.out.println(方法:+method.toString();System.out.println(方法名稱:+method.getName();System.out.println(方法修飾符:+Modifier.toString(method.getModifiers();System.out.println(方法參數(shù)列表);Class mClass=method.getParameterTypes();System.out.print(mClass.length!=0?有參數(shù):無(wú)參數(shù):);for(Class c:mClass)System.out.print(c.getName()+類(lèi)型t);System.out.println(n方法返回類(lèi)型:+method.getReturnType().getName();System.out.println(=);System.out.println(*打印構(gòu)造方法*);for(Constructor constructor:constructors)System.out.println(構(gòu)造方法:+constructor.toString();System.out.println(構(gòu)造方法名:+constructor.getName();System.out.println(構(gòu)造方法修飾符:+Modifier.toString(constructor.getModifiers();Class mClass=constructor.getParameterTypes();System.out.print(mClass.length!=0?有參數(shù):無(wú)參數(shù):);for(Class c:mClass)System.out.print(c.getName()+類(lèi)型t);System.out.println(n=); catch (ClassNotFoundException e) e.printStackTrace();日志輸出:*打印成員屬性*屬性:private java.lang.String com.wangwenjun.demo.Teacher.username名稱:username修飾符:private數(shù)據(jù)類(lèi)型:class java.lang.String=屬性:private int com.wangwenjun.demo.Teacher.age名稱:age修飾符:private數(shù)據(jù)類(lèi)型:int=屬性:private static int com.wangwenjun.demo.Teacher.total名稱:total修飾符:private static數(shù)據(jù)類(lèi)型:int=*打印成員方法*方法:public java.lang.String com.wangwenjun.demo.Teacher.getUsername()方法名稱:getUsername方法修飾符:public方法參數(shù)列表無(wú)參數(shù):方法返回類(lèi)型:java.lang.String=方法:public void com.wangwenjun.demo.Teacher.setUsername(java.lang.String)方法名稱:setUsername方法修飾符:public方法參數(shù)列表有參數(shù):java.lang.String類(lèi)型方法返回類(lèi)型:void=方法:public int com.wangwenjun.demo.Teacher.getAge()方法名稱:getAge方法修飾符:public方法參數(shù)列表無(wú)參數(shù):方法返回類(lèi)型:int=方法:public void com.wangwenjun.demo.Teacher.setAge(int)方法名稱:setAge方法修飾符:public方法參數(shù)列表有參數(shù):int類(lèi)型方法返回類(lèi)型:void=方法:public static void com.wangwenjun.demo.Teacher.setTotal(int)方法名稱:setTotal方法修飾符:public static方法參數(shù)列表有參數(shù):int類(lèi)型方法返回類(lèi)型:void=方法:public java.lang.String com.wangwenjun.demo.Teacher.toString()方法名稱:toString方法修飾符:public方法參數(shù)列表無(wú)參數(shù):方法返回類(lèi)型:java.lang.String=方法:public static int com.wangwenjun.demo.Teacher.getTotal()方法名稱:getTotal方法修飾符:public static方法參數(shù)列表無(wú)參數(shù):方法返回類(lèi)型:int=*打印構(gòu)造方法*構(gòu)造方法:public com.wangwenjun.demo.Teacher()構(gòu)造方法名:com.wangwenjun.demo.Teacher構(gòu)造方法修飾符:public無(wú)參數(shù):=構(gòu)造方法:public com.wangwenjun.demo.Teacher(java.lang.String,int)構(gòu)造方法名:com.wangwenjun.demo.Teacher構(gòu)造方法修飾符:public有參數(shù):java.lang.String類(lèi)型int類(lèi)型=通過(guò)觀察日志我們可以發(fā)現(xiàn),獲取了屬性,方法,構(gòu)造函數(shù),并且將它的屬性名稱,返回值類(lèi)型等等全部都做了打印。通過(guò)對(duì)Teacher類(lèi)的解析我們可以看出來(lái)反射機(jī)制的確非常的強(qiáng)大,它本身就非常強(qiáng)大,如果沒(méi)有這種技術(shù),像spring,ibatis,hibernate,struts等等基本上就實(shí)現(xiàn)不了或者說(shuō)很難被實(shí)現(xiàn)?!狙a(bǔ)充】在解析的時(shí)候我們還可以將對(duì)象的父類(lèi)以及父接口都得到,具體的說(shuō)明暫時(shí)不做講述,在后文中的Reflect API中就可以看得到。下面只是演示如何獲取父類(lèi)以及父接口Class superClass=clazz.getSuperclass();System.out.println(superClass.toString();Class superInterface = clazz.getInterfaces();for (int i = 0; i superInterface.length; i+) System.out.println(superInterfacei.toString();System.out.println(clazz.getPackage().toString();1.3訪問(wèn)類(lèi)的方法和屬性看完了如何動(dòng)態(tài)加載一個(gè)類(lèi),如何解析類(lèi)的結(jié)構(gòu),那么我們看看如何利用解析出來(lái)的結(jié)果對(duì)中的方法進(jìn)行使用呢?需要說(shuō)明的一點(diǎn)是在訪問(wèn)類(lèi)的方法與屬性之前呢必須先解析它,否則我們是無(wú)法獲得類(lèi)中所包含的一切信息。為了能更加的清楚一些我們寫(xiě)一個(gè)簡(jiǎn)單的java對(duì)象,與文中的teacher類(lèi)比較類(lèi)似,但是相對(duì)teacher來(lái)說(shuō)顯得稍微簡(jiǎn)單一些。代碼如下所示:package com.wangwenjun.demo;public class Student public String name;public static int count=100;public Student()super();public Student(String name)super(); = name;public void setValue(String name) = name;public void showCount()System.out.println(Student對(duì)象被實(shí)例化了+count+次);public String toString()return Name:++,調(diào)用次數(shù):+count; 訪問(wèn)name屬性的操作方法:package com.wangwenjun.demo;import java.lang.reflect.Field;public class ReflectionStudent public static void main(String args) throws ClassNotFoundException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException Student s = new Student(zhangsan);Class clazz = s.getClass();Field f=clazz.getField(name);Object o=f.get(s);System.out.println(修改前:+f.getName()+的值:+o);f.set(s, 張三);o=f.get(s);System.out.println(修改后:+f.getName()+的值:+o);打印語(yǔ)句:修改前:name的值:zhangsan修改后:name的值:張三 訪問(wèn)setValue方法的操作方法package com.wangwenjun.demo;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class ReflectionStudent public static void main(String args) throws ClassNotFoundException, SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, NoSuchMethodException, InvocationTargetException Student s = new Student(zhangsan);Class clazz = s.getClass();Method m = clazz.getMethod(setValue, new ClassString.class);m.invoke(s, new Object張三);System.out.println(s.toString();執(zhí)行結(jié)果后打印信息為:Name:張三,調(diào)用次數(shù):101通過(guò)上述代碼可以看出來(lái),name的值之前”zhangsan”,然后通過(guò)調(diào)用setValue方法將值更改為了”張三”; 訪問(wèn)類(lèi)的有參構(gòu)造方法在這里我演示了如何訪問(wèn)Student類(lèi)的構(gòu)造方法,無(wú)參的構(gòu)造函數(shù)也一樣,代碼如下:package com.wangwenjun.demo;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class ReflectionStudent SuppressWarnings(unchecked)public static void main(String args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetExceptionClass clazz = Class.forName(com.wangwenjun.demo.Student);Constructor c=clazz.getConstructor(new ClassString.class);Student s=(Student) c.newInstance(new Object劉德華);System.out.println(s-+s);執(zhí)行結(jié)果為:s-Name:劉德華,調(diào)用次數(shù):101第二節(jié) Reflection API通過(guò)上文中的所有代碼應(yīng)該對(duì)Reflection API的使用了解了大部分了,Reflection中的API也沒(méi)有太多的接口和類(lèi),學(xué)習(xí)者應(yīng)該按個(gè)去測(cè)試也應(yīng)該沒(méi)有什么問(wèn)題接口摘要AnnotatedElement表示目前正在此 VM 中運(yùn)行的程序的一個(gè)已注釋元素。GenericArrayTypeGenericArrayType 表示一種數(shù)組類(lèi)型,其組件類(lèi)型為參數(shù)化類(lèi)型或類(lèi)型變量。GenericDeclaration聲明類(lèi)型變量的所有實(shí)體的公共接口。InvocationHandlerInvocationHandler 是代理實(shí)例的調(diào)用處理程序 實(shí)現(xiàn)的接口。Member成員是一種接口,反映有關(guān)單個(gè)成員(字段或方法)或構(gòu)造方法的標(biāo)識(shí)信息。ParameterizedTypeParameterizedType 表示參數(shù)化類(lèi)型,如 Collection。TypeType 是 Java 編程語(yǔ)言中所有類(lèi)型的公共高級(jí)接口。TypeVariableTypeVariable 是各種類(lèi)型變量的公共高級(jí)接口。WildcardTypeWildcardType 表示一個(gè)通配符類(lèi)型表達(dá)式,如 ?、? extends Number 或 ? super Integer。 類(lèi)摘要AccessibleObjectAccessibleObject 類(lèi)是 Field、Method 和 Constructor 對(duì)象的基類(lèi)。ArrayArray 類(lèi)提供了動(dòng)態(tài)創(chuàng)建和訪問(wèn) Java 數(shù)組的方法。ConstructorConstructor 提供關(guān)于類(lèi)的單個(gè)構(gòu)造方法的信息以及對(duì)它的訪問(wèn)權(quán)限。FieldField 提供有關(guān)類(lèi)或接口的單個(gè)字段的信息,以及對(duì)它的動(dòng)態(tài)訪問(wèn)權(quán)限。MethodMethod 提供關(guān)于類(lèi)或接口上單獨(dú)某個(gè)方法(以及如何訪問(wèn)該方法)的信息。ModifierModifier 類(lèi)提供了 static 方法和常量,對(duì)類(lèi)和成員訪問(wèn)修飾符進(jìn)行解碼。ProxyProxy 提供用于創(chuàng)建動(dòng)態(tài)代理類(lèi)和實(shí)例的靜態(tài)方法,它還是由這些方法創(chuàng)建的所有動(dòng)態(tài)代理類(lèi)的超類(lèi)。ReflectPermission反射操作的 Permission 類(lèi)。 異常摘要InvocationTargetExceptionInvocationTargetException 是一種包裝由調(diào)用方法或構(gòu)造方法所拋出異常的經(jīng)過(guò)檢查的異常。MalformedParameterizedTypeException當(dāng)反射方法遇到語(yǔ)義錯(cuò)誤的參數(shù)化類(lèi)型,而反射方法需要實(shí)例化該類(lèi)型時(shí),拋出該異常。UndeclaredThrowableException如果代理實(shí)例的調(diào)用處理程序的 invoke 方法拋出一個(gè)經(jīng)過(guò)檢查的異常(不可分配給 RuntimeException 或 Error 的 Throwable),且該異常不可分配給該方法(在代理實(shí)例上調(diào)用該方法,并將其指派到調(diào)用處理程序)的 throws 子句中聲明的任何異常類(lèi),則由代理實(shí)例上的方法調(diào)用拋出此異常。 錯(cuò)誤摘要GenericSignatureFormatError當(dāng)需要解釋類(lèi)型、方法或構(gòu)造方法的一般簽名信息的反射方法遇到語(yǔ)法錯(cuò)誤的簽名屬性時(shí),拋出該錯(cuò)誤。上述的包結(jié)構(gòu)是我從API中粘貼出來(lái)的,有時(shí)間的話可以逐一進(jìn)行test case練習(xí)。第三節(jié) 如何使用反射機(jī)制截止到現(xiàn)在,上面已經(jīng)演示了若干個(gè)關(guān)于使用反射機(jī)制的demo,閱讀者應(yīng)該對(duì)此有一個(gè)比較籠統(tǒng)的認(rèn)識(shí),但是為了更加詳盡的說(shuō)明一下,還是做簡(jiǎn)單的整理說(shuō)明: 首先,知道何時(shí)才會(huì)去使用反射;首先我們需要明確的一點(diǎn)是,為什么要去使用反射機(jī)制呢?使用反射機(jī)制的主要原因是,在運(yùn)行時(shí)我們不能事先知道需要使用那一個(gè)類(lèi),所以就需要在運(yùn)行時(shí)動(dòng)態(tài)的加載,如果能事先知道的話,就沒(méi)有必要使用反射機(jī)制,反射機(jī)制畢竟是一個(gè)耗時(shí)的操作。 其次,需要加載類(lèi);需要將動(dòng)態(tài)使用的類(lèi)加載進(jìn)來(lái)。 再次,解析類(lèi);加載完畢之后需要對(duì)類(lèi)進(jìn)行解析; 最后,訪問(wèn)類(lèi);通過(guò)反射API進(jìn)行類(lèi)的成員信息的訪問(wèn)。第四節(jié) 通過(guò)反射機(jī)制訪問(wèn)數(shù)組為什么將反射機(jī)制訪問(wèn)數(shù)組作為一個(gè)單獨(dú)的章節(jié),是因?yàn)槲腋杏X(jué)它比較重要并且感覺(jué)它稍微復(fù)雜一些。在class中有一個(gè)方法getComponentType(),該方法的作用為:返回表示數(shù)組組件類(lèi)型的 Class。如果此類(lèi)不表示數(shù)組類(lèi),則此方法返回 null。4.1 動(dòng)態(tài)生成數(shù)組比如說(shuō)我們要?jiǎng)討B(tài)生成一個(gè)string類(lèi)型的數(shù)組,并且它的長(zhǎng)度為5package com.wangwenjun.demo;import java.lang.reflect.Array;public class ArraysTestOne public static void main(String args) Class clazz = String.class;Object objArrays = Array.newInstance(clazz, 5);for(int i=0;i5;i+)Array.set(objArrays, i, i+);for(int i=0;i5;i+)System.out.println(Array.get(objArrays, i);System.out.println(=);String strs = (String) objArrays;for(String s:strs)System.out.println(s);程序的執(zhí)行結(jié)果為:01234=012344.2 動(dòng)態(tài)擴(kuò)展數(shù)組假設(shè)我們現(xiàn)在有一個(gè)String類(lèi)型的數(shù)組,其長(zhǎng)度為5,在使用的時(shí)候我們需要將其更改為10個(gè)長(zhǎng)度,這個(gè)時(shí)侯我們?cè)撊绾稳プ瞿?,想想按照我們通常的辦法,該需求簡(jiǎn)直是不可想象的,但是通過(guò)反射機(jī)制就可以完全辦得到。package com.wangwenjun.demo;import java.lang.reflect.Array;public class ArraysTestOne SuppressWarnings(unchecked)public static void main(String args) String strs = new Stringa,b,c,d,e;System.out.println(修改之前長(zhǎng)度為:+strs.length);for(String s:strs)System.out.print(s+t);System.out.println();Class clazz = strs.getClass().getComponentType();Object objNew =Array.newInstance(clazz, strs.length*2);int length = (String)objNew).length;System.out.println(修改之后長(zhǎng)度為:+length);for(int i=0;istrs.length;i+)Array.set(objNew, i, Array.get(strs, i);String objStrs = (String)objNew;for(String s:objStrs)System.out.print(s+t);代碼執(zhí)行結(jié)果如下:修改之前長(zhǎng)度為:5abcde修改之后長(zhǎng)度為:10abcdenullnullnullnullnull第五節(jié) 動(dòng)態(tài)代理Java中的反射機(jī)制API封裝了動(dòng)態(tài)代理相關(guān)的API,這樣在我們使用的時(shí)候就會(huì)方便很多,要知道什么是動(dòng)態(tài)代理,首先了解一下靜態(tài)代理。5.1 靜態(tài)代理為什么要使用代理呢?在我們要實(shí)現(xiàn)某個(gè)功能的時(shí)候可能會(huì)做其他一些不相干的事情,這些不相干的事情其實(shí)不用出現(xiàn)在我們的業(yè)務(wù)邏輯處理代碼中,這樣會(huì)給程序的業(yè)務(wù)邏輯帶來(lái)一些較差的可讀性,并且提高了維護(hù)的成本。所以我們往往喜歡將比較純粹的業(yè)務(wù)邏輯進(jìn)行單獨(dú)的設(shè)計(jì),其他的事情交由其它的類(lèi)來(lái)做。【需求】:現(xiàn)在需要計(jì)算一個(gè)兩數(shù)相加的需求,我們往往會(huì)在加法運(yùn)算之前打印參數(shù)的信息,并且在運(yùn)算之后打印結(jié)果信息,以往我們大多都會(huì)這樣做package com.wangwenjun.demo;public class ProxyTest public int add(int arg1,int arg2)System.out.println(被加數(shù)為:+arg1);System.out.println(加數(shù)為:+arg2);int result = arg1+arg2;System.out.println(運(yùn)算結(jié)果為:+result);return result;public static void main(String args) int result=new ProxyTest().add(3, 4);System.out.println(執(zhí)行結(jié)果為:+result);通過(guò)以上的代碼可以看出add方法其實(shí)就是做了一個(gè)加法的操作,但是呢有三條日志信息都將其進(jìn)行了分割,相對(duì)add操作,日志與其是沒(méi)有任何關(guān)系的,這樣在該方法中又增加了三條無(wú)謂的代碼,所以呢,我們就有了代理機(jī)制,下面看看什么叫做代理。【Subject】package com.wangwenjun.demo;public interface Subject public int add(int arg1,int arg2);【RealSubject】package com.wangwenjun.demo;public class RealSubject implements Subject public int add(int arg1, int arg2) return arg1+arg2;【Proxy】package com.wangwenjun.demo;public class Proxy implements Subjectprivate Subject obj = null;public Proxy(Subject obj)this.obj = obj;public int add(int arg1, int arg2) System.out.println(被加數(shù)為:+arg1);System.out.println(加數(shù)為:+arg2);return obj.add(arg1, arg2);【Test Case】package com.wangwenjun.demo;public class ProxyTest public static void main(String args) Subject s = new Proxy(new RealSubject();int result=s.add(3, 4);System.out.println(計(jì)算結(jié)果為:+result);通過(guò)上面的設(shè)計(jì)我們可以看得出來(lái),負(fù)責(zé)計(jì)算加法運(yùn)算的方法只是做了加法運(yùn)算,并未做其他的事情,這樣顯得業(yè)務(wù)邏輯很純粹。5.2 動(dòng)態(tài)代理靜態(tài)代理解決了業(yè)務(wù)邏輯與日志信息脫耦的一種設(shè)計(jì),但是又帶來(lái)其他的問(wèn)題,也就是說(shuō)我們有100個(gè)目標(biāo)對(duì)象,就需要設(shè)計(jì)100個(gè)代理,這樣會(huì)引起類(lèi)爆炸(類(lèi)非常多)。所以我們需要解決這樣的問(wèn)題,不過(guò)sun的jdkAPI給我們提供了現(xiàn)成的解決方案,那就是動(dòng)態(tài)代理,通過(guò)我的代碼演示,希望能夠了解什么是動(dòng)態(tài)代理,實(shí)現(xiàn)動(dòng)態(tài)代理必須繼承一個(gè)接口,這個(gè)借口就是InvocationHandler,該接口有一個(gè)方法,必須進(jìn)行實(shí)現(xiàn)Object invoke(Objectproxy,Methodmethod,Objectargs) throws Throwable現(xiàn)在開(kāi)始使用動(dòng)態(tài)代理package com.wangwenjun.demo;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class DynamicProxy implements InvocationHandlerprivate Object obj = null;public Object bind(Object obj )this.obj = obj;return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);public Object invoke(Object proxy, Method method, Object args)throws Throwable Object result = null;for(Object o:args)System.out.println(o);result = method.invoke(obj, args);return result;測(cè)試代碼如下:package com.wangwenjun.demo;public class ProxyTest public static void main(String args) DynamicProxy d =new DynamicProxy();Subject proxy=(Subject) d.bind(new RealSubject();int result=proxy.add(3, 4);System.out.println(執(zhí)行結(jié)果為:+result);打印信息:34執(zhí)行結(jié)果為:7更為詳細(xì)的關(guān)于proxy模式的文章請(qǐng)關(guān)注我后期有關(guān)24中設(shè)計(jì)模式的總結(jié)。第六節(jié) 反射機(jī)制的應(yīng)用舉例為了能讓讀者更加清晰的了解到反射機(jī)制到底能夠做什么,到底能夠給我們?cè)谝院蟮能浖_(kāi)發(fā)中帶來(lái)多大的方便,接下來(lái)我會(huì)以兩個(gè)完整的實(shí)際示例進(jìn)行詳細(xì)的示范與解析。6.1 Struts消息接受Struts有一個(gè)很方便的操作就是我們通過(guò)它的標(biāo)簽就可以完成屬性值的收集過(guò)程,如果熟悉struts的人應(yīng)該知道,只要我們?cè)陧?yè)面中配置了與javabean一一對(duì)應(yīng)的屬性名字,在后臺(tái)的處理過(guò)程中我們會(huì)將傳遞過(guò)來(lái)的值得到,當(dāng)然這些都是由struts框架為我們實(shí)現(xiàn)的,接下來(lái)我們就模擬這樣的場(chǎng)景進(jìn)行一下屬性值的收集操作。假定我們有一個(gè)登陸頁(yè)面,其中需要填寫(xiě)userName,passWord這樣兩個(gè)值,當(dāng)然在該文中不會(huì)真的去做這樣的頁(yè)面,我們會(huì)將假定的輸入保存在一個(gè)properties中去,我們定義屬性值所在的javabean為userBean,代碼如下:package com.wangwenjun.demo;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Enumeration;import java.util.Hashtable;import java.util.Properties;public class UserLoginAction private static Hashtable session=new Hashtable();private static Properties props = new Properties();/存放用戶的登錄信息staticprops.put(userName, zhangsan);props.put(passWord, admin);SuppressWarnings(unchecked)public static void main(String args) Enumeration propNames= pertyNames();while(propNames.hasMoreElements()String propName = (String) propNames.nextElement();String propValue = props.getProperty(propName);collect(propName,propValue);UserBean userBean=session.get(user);System.out.println(userBean.getUserName
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 火災(zāi)山體滑坡地震應(yīng)急預(yù)案(3篇)
- 軟件設(shè)計(jì)師考試自我激勵(lì)與提升策略試題及答案
- 逆襲成功的軟件設(shè)計(jì)師考試試題及答案
- 企業(yè)網(wǎng)絡(luò)服務(wù)模型試題及答案
- 高考數(shù)學(xué)解析能力提升指南試題及答案
- 2025年網(wǎng)絡(luò)攻防技能試題及答案
- 法學(xué)概論的影響力試題與答案分析
- 面對(duì)失敗的成長(zhǎng)經(jīng)歷2023年高考作文試題及答案
- 網(wǎng)絡(luò)測(cè)量工具試題及答案
- 多媒體技術(shù)在教研中的應(yīng)用計(jì)劃
- 上海市徐匯區(qū)2025屆八下物理期末考試試題含解析
- 2025浙江省樂(lè)清蒼南永嘉二模聯(lián)考科學(xué)試題卷
- Java高級(jí)軟件開(kāi)發(fā)面試題及答案
- 3.4 羧酸的衍生物 課件高二下學(xué)期化學(xué)人教版(2019)選擇性必修3
- 2025年消防安全培訓(xùn)考試試卷及完整答案
- 2024年河北省井陘縣事業(yè)單位公開(kāi)招聘警務(wù)崗筆試題帶答案
- 2025年信息科技與創(chuàng)新能力考核試題及答案
- 2025年智慧城市建設(shè)相關(guān)知識(shí)考試試卷及答案
- 2025年4月自考00522英語(yǔ)國(guó)家概況答案及評(píng)分參考
- 2025年江西南昌初三一模中考語(yǔ)文試卷試題(含答案詳解)
- 2025年吉林省長(zhǎng)春市中考一模歷史試題(原卷版+解析版)
評(píng)論
0/150
提交評(píng)論