Java反射与代理SCSJ002思考已知类的名称,如何实例化类为对象;如”com.softeem.mvc.core.ActionServlet”,变成对象。(不是用new)已知一个类的某个方法名称(字符串形式),如何调用这个方法;如何将一个对象里所有属性的值拷贝到另外一个对象里面去?什么是反射反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力反射本身并不是一个新概念,尽管计算机科学赋予了反射概念新的含义。在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义反射在运行时判断任意一个对象所属的类在运行时构造任意一个类的对象在运行时判断任意一个类所具有的成员变量和方法在运行时调用任意一个对象的方法动态语言程序运行时,允许改变程序结构和变量类型,这种语言称为动态语言;从这个观点来看java并不是动态语言java反射机制尽管在这样的定义与分类下java不是动态语言,但是它却有一个非常突出的动态相关机制:reflection,意思是反射,影像,倒影;在java中指的是可以在运行时加载,探知和使用编译期间完全未知的classes,简而言之,java程序可以加载一个运行时才得知名称的class,获悉其完整构造(不包括methods定义),并生成器对象实体.或对其fields设置,或唤起其methods,这种看透class的能力被称为introspection(反省,内观,自省).所谓反射,就是把一个java类中的成分反射成相应的java类javaReflectionAPI在jdk中,主要由以下类实现java反射机制,这些类都位于java.lang.reflect包中Class类:表示一个类Field类:代表类中的属性Method类:代表类中的方法Constructor类:代表类的构造方法Array类:提供了动态创建数组,以访问数组的元素的静态方法反射其实就是把一个java类的所有成分反射成为对应的java类对象实例化方式1,直接实例化对象Studentstudent=newStudent();2,根据类名实例化StringclzName=“com.softeem.j2se.Student”;Objecto=Class.forName(clzName).newInstance();Students=(Student)o;Class类Class类的实例表示正在运行的Java应用程序中的类和接口,Class表示一个类的描述。Studentobj=newStudent();Classc1=obj.getClass();Classc2=Student.class;Classc3=Class.forName(“package_name.Student”);System.out.println(c1.getName());System.out.println(c2.getName());System.out.println(c3.getName());Class类的方法Constructor[]getConstructors()返回一个包含某些Constructor对象的数组,这些对象反映此Class对象所表示的类的所有公共构造方法。FieldgetField(Stringname)返回一个Field对象,它反映此Class对象所表示的类或接口的指定公共成员字段。Field[]getFields()|Field[]getDeclaredFields()返回一个包含某些Field对象的数组,这些对象反映此Class对象所表示的类或接口的所有可访问公共字段。Method[]getMethods()返回一个包含某些Method对象的数组,这些对象反映此Class对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共member方法。打印一个类的所有方法,含父类ClassmyClass=Class.forName(com.softeem.jsp.dao.BookDAO);Method[]methods=myClass.getMethods();for(inti=0;imethods.length;i++){System.out.println(methods[i].getName());}打印一个类的所有属性ClassmyClass=Class.forName(com.softeem.jsp.dao.BookDTO);Field[]fs=myClass.getDeclaredFields();for(inti=0;ifs.length;i++){System.out.println(fs[i].getName());}打印一个类的所有构造器ClassmyClass=Class.forName(com.softeem.jsp.dao.BookDTO);Constructor[]fs=myClass.getConstructors();for(inti=0;ifs.length;i++){System.out.println(fs[i].getName());}Method类Method提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。getExceptionTypes,getName,getParameterTypes,getReturnType,invokeInvoke,无参方法调用ClassmyClass=Class.forName(com.softeem.jsp.dao.BookDTO);Method[]fs=myClass.getMethods();for(inti=0;ifs.length;i++){StringmethodName=fs[i].getName();if(methodName.indexOf(get)=0){Objectret=fs[i].invoke(myClass.newInstance(),null);System.out.println(methodName+:+ret);}}Invoke,有参方法调用ClassmyClass=Class.forName(com.softeem.jsp.dao.BookDTO);Objectdao=myClass.newInstance();Methodset=myClass.getMethod(setBookName,String.class);set.invoke(dao,thinkinginJava);Methodget=myClass.getMethod(getBookName);Objectret=get.invoke(dao,null);System.out.println(ret);实例,属性值拷贝如何将一个对象里所有属性的值拷贝到另外一个对象里面去?部分代码publicstaticvoidcopyProperties(Objectto,Objectfrom){ClassclzFrom=from.getClass();ClassclzTo=to.getClass();Field[]fs=clzFrom.getDeclaredFields();for(inti=0;ifs.length;i++){Stringname=fs[i].getName().substring(0,1).toUpperCase()+fs[i].getName().substring(1);StringgetName=get+name;StringsetName=set+name;MethodgetMethod=clzFrom.getMethod(getName,null);ObjectretVal=getMethod.invoke(from,null);TyperetType=getMethod.getReturnType();MethodtoMethod=clzTo.getMethod(setName,newClass[]{retType});toMethod.invoke(to,newObject[]{retVal});}}实例,将request的值拷贝到一个Javabean中publicvoidload(HttpServletRequestrequest,Objectform)如何将request里所有的属性值拷贝到一个Javabean中,JavaBean如下定义。classBookForm{intid;StringbookName;floatprice;Stringisbn;//如下为getter和setter器}voidload(HttpServletRequestrequest,Objectform)Enumerationnames=request.getParameterNames();while(names.hasMoreElements()){Stringname=(String)names.nextElement();//获得每一个参数名,eg:userNameString[]value=request.getParameterValues(name);//获取这个参数对应的值eg:zhangsanif(value!=null){//看ActionForm里是否有name这个属性,并获取在ActionForm里的数据类型ClassfieldType=form.getClass().getDeclaredField(name).getType();StringsetName=set+name.substring(0,1).toUpperCase()+name.substring(1);Methodmethod=form.getClass().getMethod(setName,fieldType);Object[]o=transfer(fieldType,value);//判断属性是否为数组属性if(fieldType.isArray()){method.invoke(form,newObject[]{o});}else{method.invoke(form,newObject[]{o[0]});}}}部分代码privatestaticObjecttransfer(Stringvalue,ClassfieldType){Objectobj=null;if(fieldType==Integer.class||fieldType==int.class){obj=Integer.parseInt(value);}elseif(fieldType==Date.class){SimpleDateFormatsdf=newSimpleDateFormat(yyyy-MM-dd);obj=sdf.parse(value);}else{obj=value;}returnobj;}代理模式代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用代理模式代理模式一般涉及到的角色有抽象角色:声明真实对象和代理对象的共同接口代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装真实角色:代理角色所代表的真实对象,是我们最终要引用的对象Java静态代理购买+Buy()KeyboardSaler+Buy()M