收藏 分享(赏)

第14章----反射与代理.ppt

上传人:无敌 文档编号:1114098 上传时间:2018-06-12 格式:PPT 页数:48 大小:1.75MB
下载 相关 举报
第14章----反射与代理.ppt_第1页
第1页 / 共48页
第14章----反射与代理.ppt_第2页
第2页 / 共48页
第14章----反射与代理.ppt_第3页
第3页 / 共48页
第14章----反射与代理.ppt_第4页
第4页 / 共48页
第14章----反射与代理.ppt_第5页
第5页 / 共48页
点击查看更多>>
资源描述

1、1,第十四章反射与代理,本章任务,使用反射技术获取类的结构信息使用反射技术动态创建对象动态修改查询属性值动态执行方法动态创建数组并存取元素使用静态代理实现添加日志功能使用动态代理实现添加日志功能,本章目标,Java反射技术反射技术的引入反射技术的入口类Class反射技术的具体内容动态创建对象动态修改查询属性值动态执行方法动态创建数组并存取元素反射技术优缺点代理模式静态代理动态代理,反射技术的引入4-1,编译和运行时都知道类和对象的具体信息,此时直接对类和对象进行操作即可,无需反射,public class WhyClass public void method1( Student stu1 )

2、 Student stu2 = new Student();stu2.name = lkl;stu2.setAge(stu1.getAge();System.out.println(stu2.name);System.out.println(stu2.getAge();,传入Student类,而不是其他类,反射技术的引入4-2,如果编译和运行时不知道类和对象的具体信息,此时应该如何做呢?,public class WhyClass public void method2( String str ) throws Exception Class clazz = Class.forName(str

3、);Object obj = clazz.newInstance();Field fs = clazz.getFields();Method ms = clazz.getMethods();public static void main(String args) throws Exception WhyClass t = new WhyClass();t.method2(java.lang.String);t.method2(cn.jbit.reflection.Student);t.method2(java.util.Date);,使用反射技术来实现,实参:传入具体的类名,形参:动态传入类名

4、,反射的应用场合在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息反射的作用通过反射可以使程序代码访问装载到JVM 中的类的内部信息获取已装载类的属性信息获取已装载类的方法获取已装载类的构造方法信息,反射技术的引入4-3,在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中Class类:代表一个类Field 类:代表类的成员变量(属性)Method类:代表类的成员方法Constructor 类:代表类的构造方法Array类:提供了动态创建数组,以及访问数组的元素的静态方法,反射技术的引入4-4,Class类

5、是Java 反射机制的起源和入口用于获取与类相关的各种信息提供了获取类信息的相关方法Class类继承自Object类Class类是所有类的共同的图纸每个类有自己的对象,好比图纸和实物的关系每个类也可看做是一个对象,有共同的图纸Class,存放类的结构信息,能够通过相应方法取出相应信息类的名字属性方法构造方法父类和接口,反射技术的入口类Class5-1,反射技术的入口类Class5-2,Class类的常用方法,反射技术的入口类Class5-3,public class TestClass public static void main(String args) throws Exception

6、Class clazz = Class.forName(java.lang.Object);/ Class clazz = Class.forName(java.lang.String);System.out.println(-类的字段-);Field fields = clazz.getDeclaredFields();for (Field field : fields)System.out.println(field.getName() + + field.getType();System.out.println(-类的方法-);Method methods = clazz.getDecl

7、aredMethods();for (Method method : methods)System.out.println(method.getName();System.out.println(-类的构造方法-);Constructor constructors = clazz.getDeclaredConstructors();for (Constructor constructor : constructors) System.out.println(constructor);System.out.println(-类所在包、完整名称、父类-);System.out.println(cl

8、azz.getPackage().getName();System.out.println(clazz.getName();System.out.println(clazz.getSuperclass();,反射技术的入口类Class5-4,为一个class生成对应的Class对象,反射技术的入口类Class5-5,public class TestClass2 public static void main(String args) throws ClassNotFoundException /方法1:对象.getClass()Student stu=new Student();Class

9、clazz=stu.getClass();String str=Hello World;clazz=str.getClass();/方法2:类.classclazz= Student.class;clazz=String.class;clazz=Integer.class;clazz =int.class;/方法3:Class.forName()clazz=Class.forName(java.lang.String);clazz=Class.forName(java.util.Date);/方法4:包装类.TYPEclazz=Integer.TYPE;clazz=Void.TYPE;,方法1

10、:通过Class的newInstance()方法该方法要求该Class对象的对应类有无参构造方法执行newInstance()实际上就是执行无参构造方法来创建该类的实例,使用反射动态创建对象2-1,public class ConstructorTest public static void main(String args) throws Exception /方法1:调用Class的newInstance方法,仅适用于无参构造方法Class clazz=Class.forName(cn.jbit.reflection.Student);Object obj=clazz.newInstanc

11、e();,相当于执行语句: Student stu = new Student();,方法2:通过Constructor的newInstance()方法先使用Class对象获取指定的Constructor对象再调用Constructor对象的newInstance()方法来创建该Class对象对应类的对象通过该方法可选择使用指定构造方法来创建对象,使用反射动态创建对象2-2,public class ConstructorTest public static void main(String args) throws Exception / 方法2:调用Constructor的newInsta

12、nce方法,适用所有构造方法Class clazz = Class.forName(cn.jbit.reflection.Student);Constructor cons = clazz.getConstructor(new Class String.class,int.class, float.class );Object obj = cons.newInstance(new Object lkl, 32, 56.5f );System.out.println(obj); /也可以调用无参构造方法,只是比方法1复杂obj=clazz.getConstructor(new Class).ne

13、wInstance(new Object);obj=clazz.getConstructor().newInstance();System.out.println(obj);,相当于执行语句: Student stu=new Student(lkl,32,56.5f);,相当于执行语句: Student stu=new Student();,练习Class类和Constructor类,需求说明:使用多种方法生成一个Student类的Class对象使用Class类获取String和Student类的结构信息并输出使用反射技术动态创建Student类的对象通过无参构造方法通过有参构造方法实现步骤参

14、考本专题实现步骤和代码,完成时间:25分钟,共性问题集中讲解,常见调试问题及解决办法代码规范问题,共性问题集中讲解,通过Class对象的getFields()或者getField()方法可以获得该类所包括的全部Field属性或指定Field属性。Field类提供了以下方法来访问属性getXxx(Object obj):获取obj对象该Field的属性值。此处的Xxx对应8个基本数据类型,如果该属性类型是引用类型则直接使用get(Object obj)setXxx(Object obj,Xxx val):将obj对象的该Field赋值val。此处的Xxx对应8个基本数据类型,如果该属性类型是引用

15、类型则直接使用set(Object obj, Object val)setAccessible(Boolean flag):若flag为true,则取消属性的访问权限控制,即使private属性也可以进行访问,使用反射动态修改查询属性值2-1,使用反射动态修改查询属性值2-2,public class FieldTest public static void main(String args) throws Exception Class clazz = Class.forName(cn.jbit.reflection.Student);Object obj = clazz.newInstan

16、ce();/ 调用getDeclaredField(name) 取得name属性对应的Field对象Field f = clazz.getDeclaredField(name);/ 取消属性的访问权限控制,即使private属性也可以进行访问。f.setAccessible(true);/ 调用get()方法取得对应属性值。System.out.println(f.get(obj); /相当于obj.getName();/ 调用set()方法给对应属性赋值。f.set(obj, lkl); /相当于obj.setName(lkl); / 调用get()方法取得对应属性修改后的值。System.

17、out.println(f.get(obj);,通过Class对象的getMethods() 方法可以获得该类所包括的全部方法, 返回值是Method通过Class对象的getMethod()方法可以获得该类所包括的指定方法, 返回值是Method每个Method对象对应一个方法,获得Method对象后,可以调用其invoke() 来调用对应方法Object invoke(Object obj,Object args):obj代表当前方法所属的对象的名字,args代表当前方法的参数列表,返回值Object是当前方法的返回值,即执行当前方法的结果。,使用反射动态执行方法2-1,使用反射动态执行方

18、法2-2,public class TestMethod public int add(int x, int y) return x + y;public void shout(String name) System.out.println(my name is+name);public static void main(String args) throws Exception / 创建该类的一个对象Class clazz = TestMethod.class;Object obj = clazz.newInstance();/ 调用该对象的add方法Method amethod=clazz

19、.getMethod(add,new Classint.class, int.class);Object result = amethod.invoke(obj, new Object 5, 7 );System.out.println(result);/ 调用该对象的shout方法Method smethod=clazz.getMethod(shout,new ClassString.class);smethod.invoke(obj, new Object lkl );,相当于执行语句:TestMethod tm=new TestMethod();int sum=tm.add(5, 7);

20、System.out.println(sum);tm.shout(lkl);,练习Field类和Method类,需求说明:使用反射修改和查询Student类的name属性使用反射动态执行TestMethod类的add方法和shout方法实现步骤参考本专题实现步骤和代码,完成时间:20分钟,共性问题集中讲解,常见调试问题及解决办法代码规范问题,共性问题集中讲解,在java.lang.reflect包下提供了Array类,包括一系列static方法,通过这些方法可动态的创建数组、给元素赋值、取出元素值等Array提供的主要方法如下:static Object newInstance(Class c

21、omponentType, int dim) :创建一个具有指定的组件类型和维度的新数组static void setXxx(Object array, int index ,xxx val):给数组对象array中第index个元素赋值valstatic xxx getXxx(Object array, int index):以 xxx形式返回指定数组对象array中第index个元素值,使用反射动态创建数组并存取元素3-1,使用反射动态创建数组并存取元素3-2,public class ArrayTest1 public static void main(String args) thro

22、ws Exception / 创建一个含有10个元素的整型数组Class clazz = Class.forName(java.lang.Integer);Object arr = Array.newInstance(clazz, 10);/ Object arr=Array.newInstance(Integer.TYPE, 10);/ 给第五个元素赋值Array.set(arr, 5, 20);/ Array.setInt(arr, 5, 20);/ 取出第五个元素值并输出Object elem = Array.get(arr, 5);System.out.println(elem);,相

23、当于执行语句: int arr=new int10; arr5=20; System.out.println(arr5);,使用反射动态创建数组并存取元素3-3,public class ArrayTest2 public static void main(String args) throws Exception / 创建一个含有10*15*18个元素的整型数组int dims = 10, 15, 18 ;Object arr = Array.newInstance(int.class, dims);/ 给arr5810赋值Object arr5 = Array.get(arr, 5);Ob

24、ject arr58 = Array.get(arr5, 8);Array.set(arr58, 10, 30);/ 取出arr5810值并输出Object elem = Array.get(arr58, 10);System.out.println(elem);,相当于执行语句: int arr =new int101518; arr5810=20; System.out.println(arr5810);,练习Array类,需求说明:使用反射动态创建一维整型数组并存取元素使用反射动态创建多维整型数组并存取元素实现步骤参考本专题实现步骤和代码,完成时间:20分钟,共性问题集中讲解,常见调试问

25、题及解决办法代码规范问题,共性问题集中讲解,反射提高了Java程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类反射是其它一些常用语言,如C、C+、Fortran 或者Pascal等都不具备的Java反射技术应用领域很广,如软件测试、 EJB、JavaBean等许多流行的开源框架例如Struts、Hibernate、Spring在实现过程中都采用了该技术,反射技术优缺点2-1,反射的缺点性能问题使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此Java反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建

26、议使用。使用反射会模糊程序内部逻辑程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。,反射技术优缺点2-2,小结,Java反射技术的主要实现类有哪些,其作用分别是什么?生成一个Class对象的方法主要有哪些?getFields()和getDeclaredFields()有什么区别?反射技术的优缺点有哪些?,代理模式简介2-1,代理模式是23中设计模式之一代理模式的作用为其他对象提供一种代理以控制对目标对象的访问。某些情况下客户不想或不能直接引用另一个对象,而代理对象可在客户端和目标对象间起到中介作用代理模式的分类静态代理动态代理

27、,代理模式简介2-2,代理模式一般涉及到的角色抽象角色:真实对象和代理对象的共同接口真实角色:真实对象,最终要引用的对象代理角色内部含有对真实对象的引用,从而可以操作真实对象提供与真实对象相同的接口以便在任何时刻代替真实对象可在执行真实对象操作前后附加其他操作,相当于对真实对象进行封装,静态代理5-1,抽象角色,/* * 学生管理接口 * author 北大青鸟 * */public interface StuManager /* * 按照指定id删除学生 * param id */public void deleteStu(int id);/* * 查询指定id的学生 * param id

28、* return */public String selectStu(int id);,静态代理5-2,真实角色,/* * 学生管理实现类 * author 北大青鸟 */public class StuManagerImpl implements StuManager public void deleteStu(int id) System.out.println(deleteStu);public String selectStu(int id) System.out.println(selectStu);return lkl;,静态代理5-3,代理角色,/ 学生管理静态代理类, 在进行操

29、作前记录操作日志 public class StuManagerSproxy implements StuManager StuManager stumanager;public StuManagerSproxy() this.stumanager = new StuManagerImpl();public void deleteStu(int id) log(deleteStu);stumanager.deleteStu(id);public String selectStu(int id) log(selectStu);return stumanager.selectStu(id);pub

30、lic void log(String oper)System.out.println(log before execute + oper);,含有对真实对象的引用,删除操作之前添加日志,查询操作之前添加日志,记录操作日志,静态代理5-4,测试类,public class Test public static void main(String args) System.out.println(-不使用静态代理进行操作-);/创建目标类对象,不使用静态代理StuManager sm1=new StuManagerImpl();/删除指定id学生sm1.deleteStu(5);/查询指定id学生

31、信息System.out.println(sm1.selectStu(5);System.out.println(-使用静态代理进行操作-);/创建静态代理类对象StuManager sm2=new StuManagerSproxy();/删除指定id学生sm2.deleteStu(5);/查询指定id学生信息System.out.println(sm2.selectStu(5);,静态代理5-5,优点不需要修改目标对象就实现了功能的增加缺点真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。如果事先并不知道真实角色则无法使用一个真实角色必须对应一个代理角色,如果大量使用会导致类的急剧

32、膨胀,如果事先并不知道真实角色,该如何使用代理呢?动态代理,动态代理6-1,Java动态代理类位于java.lang.reflect包下,主要涉及到以下两个类InvocationHandler接口Proxy类InvocationHandler接口仅定义了一个方法public object invoke(Object obj,Method method, Object args)obj一般是指代理类method是被代理的方法args为该方法的参数数组 这个抽象方法在代理类中动态实现,动态代理6-2,Proxy类即为动态代理类,主要方法包括protected Proxy(InvocationHan

33、dler h) 构造函数,用于给内部的h赋值static Object newProxyInstance(ClassLoader loader, Class interfaces, InvocationHandler h) 返回代理类的一个实例loader是类装载器interfaces是真实类所拥有的全部接口的数组static Class getProxyClass (ClassLoader loader, Class interfaces) 获得一个代理类,动态代理6-3,抽象角色和真实角色为方便起见,采用了和静态代理相同的类但必须明确一个动态代理类可适用多个抽象角色和真实角色,/* * 学

34、生管理接口 * author 北大青鸟 * */public interface StuManager /* * 按照指定id删除学生 * param id */public void deleteStu(int id);/* * 查询指定id的学生 * param id * return */public String selectStu(int id);,/* * 学生管理实现类 * author 北大青鸟 */public class StuManagerImpl implements StuManager public void deleteStu(int id) System.out

35、.println(deleteStu);public String selectStu(int id) System.out.println(selectStu);return lkl;,动态代理6-4,定义LogHandler包含对真实对象的引用实现InvocationHandler 接口返回动态代理对象,public class LogHandler implements InvocationHandler Object target; public LogHandler(Object target) this.target = target;public Object invoke(Ob

36、ject proxy, Method method, Object args)throws Throwable if (method.getName().equals(deleteStu) log();Object result = method.invoke(target, args); return result;public void log() System.out.println(log before execute);public Object getProxy() return Proxy.newProxyInstance(target.getClass().getClassLo

37、ader(),target.getClass().getInterfaces(), this);,删除操作之前添加日志,通过反射调用真实对象方法,对真实对象的引用,返回动态代理对象,实现记录日志功能,动态代理6-5,测试类,public class Test public static void main(String args) System.out.println(-不采用动态代理-);StuManager stuManager=new StuManagerImpl();stuManager.deleteStu(4);System.out.println(stuManager.select

38、Stu(5);System.out.println(-采用动态代理-);LogHandler lh=new LogHandler(stuManager);StuManager up=(StuManager)lh.getProxy();up.deleteStu(4);System.out.println(up.selectStu(5); ,动态代理6-6,动态代理步骤创建一个实现接口InvocationHandler的类在invoke方法内通过反射调用真实对象的方法,并添加附加操作创建被代理的类以及接口通过Proxy类的newProxyInstance() 创建一个代理必须传入一个Invocat

39、ionHandler对象通过代理调用方法LogHandler类就是动态代理类吗?,LogHandler类不是动态代理类!newProxyInstance()方法返回的才是动态代理对象,是在运行时动态创建的,两种代理模式的区别,静态代理和动态代理的比较静态代理类确实存在,动态代理类在运行期动态生成 一个真实角色必须对应一个静态代理角色,而动态代理大大减少了代理类的数量动态代理类不会作实质性的工作,在生成它的实例时必须提供一个handler,由它接管实际的工作(会自动执行handler的invoke方法),练习代理模式,需求说明:使用静态代理添加日志管理功能使用动态代理添加日志管理功能实现步骤参考本专题实现步骤和代码,完成时间:25分钟,共性问题集中讲解,常见调试问题及解决办法代码规范问题,共性问题集中讲解,总结,Java反射技术的主要实现类有哪些,其作用分别是什么?生成一个Class对象的方法主要有哪些?代理模式中一般涉及哪三个角色?静态代理和动态代理的区别有哪些?,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 经营企划

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报