您好,欢迎访问三七文档
Java反射机制n概述本课程主要讲述Java反射机制本课程要求大家对Java泛型知识有所了解,因为程序代码中大量使用了泛型相关知识2010-12-2第2页成都天府软件园有限公司TOSC-ITOn目录Java反射简介………………………4ClassObject………………………8动态实例化………………………11Method使用………………………14Field使用………………………16实用案例………………………18总结………………………222010-12-2第3页成都天府软件园有限公司TOSC-ITOn动态语言“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。尽管在这样的定义与分类下Java不是动态语言,它却有着一个非常突出的动态相关机制:Reflection。2010-12-2第4页成都天府软件园有限公司TOSC-ITOn什么是反射反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。2010-12-2第5页成都天府软件园有限公司TOSC-ITOnJava反射的应用Spring框架:IOC(控制反转)Hibernate框架:关联映射等白盒测试2010-12-2第6页成都天府软件园有限公司TOSC-ITOnJava反射相关的APIjava.lang包下–ClassT:表示一个正在运行的Java应用程序中的类和接口,是Reflection的起源java.lang.reflect包下–Field类:代表类的成员变量(也称类的属性)–Method类:代表类的方法–Constructor类:代表类的构造方法–Array类:提供了动态创建数组,以及访问数组的元素的静态方法2010-12-2第7页成都天府软件园有限公司TOSC-ITOnClassT类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象Class没有公共构造方法。Class对象是在加载类时由Java虚拟机以及通过调用类加载器中的defineClass方法自动构造的,因此不能显式地声明一个Class对象Class是Reflection起源。要想操纵类中的属性和方法,都必须从获取Classobject开始2010-12-2第8页成都天府软件园有限公司TOSC-ITOn第一个实例就用大家非常熟悉的ArrayList类,我们尝试来获取ArrayList申明的方法。publicstaticvoidmain(String[]args){ArrayListaList=newArrayList();ClassalClass=aList.getClass();System.out.println(①+alClass);System.out.println(②+alClass.getName());Method[]alMethod=alClass.getDeclaredMethods();for(Methodmethod:alMethod){System.out.println(③+method);System.out.println(④+method.getName());}}第一步永远是获得被反射类的Class对象!案例一2010-12-2第9页成都天府软件园有限公司TOSC-ITOn获取ClassObject获取方式说明示例object.getClass()每个对象都有此方法获取指定实例对象的ClassListlist=newArrayList();ClasslistClass=list.getClass();class.getSuperclass()获取当前Class的继承类ClassListlist=newArrayList();ClasslistClass=list.getClass();ClasssuperClass=listClass.getSuperclass();Object.class.class直接获取ClasslistClass=ArrayList.class;Class.forName(类名)用Class的静态方法,传入类的全称即可try{Classc=Class.forName(java.util.ArrayList);}catch(ClassNotFoundExceptione){e.printStackTrace();}Primitive.TYPE基本数据类型的封装类获取Class的方式ClasslongClass=Long.TYPE;ClassintegerClass=Integer.TYPE;ClassvoidClass=Void.TYPE;2010-12-2第10页成都天府软件园有限公司TOSC-ITO根据具体情形和个人爱好,可以选择下面任何一种方式获得Class对象n通过反射实例化对象平常情况我们通过newObject来生成一个类的实例,但有时候我们没法直接new,只能通过反射动态生成。实例化无参构造函数的对象,两种方式:–①Class.newInstance();–②Class.getConstructor(newClass[]{}).newInstance(newObject[]{})实例化带参构造函数的对象:–clazz.getConstructor(Class?...parameterTypes).newInstance(Object...initargs)2010-12-2第11页成都天府软件园有限公司TOSC-ITOn案例准备首先我们新建一个JavaBean—User,User继承自另一个Bean—BaseUser。注意:这两个Bean的属性和方法的作用域!2010-12-2第12页成都天府软件园有限公司TOSC-ITOn案例二:动态实例化2010-12-2第13页成都天府软件园有限公司TOSC-ITOn通过反射调用Method(方法)获得当前类以及超类的publicMethod:–Method[]arrMethods=classType.getMethods();获得当前类申明的所有Method:–Method[]arrMethods=classType.getDeclaredMethods();获得当前类以及超类指定的publicMethod:–Methodmethod=classType.getMethod(Stringname,Class?...parameterTypes);获得当前类申明的指定的Method:–Methodmethod=classType.getDeclaredMethod(Stringname,Class?...parameterTypes)通过反射动态运行指定Method:–Objectobj=method.invoke(Objectobj,Object...args)2010-12-2第14页成都天府软件园有限公司TOSC-ITOn案例三:动态操纵Method2010-12-2第15页成都天府软件园有限公司TOSC-ITOn通过反射调用Field(变量)获得当前类以及超类的publicField:–Field[]arrFields=classType.getFields();获得当前类申明的所有Field:–Field[]arrFields=classType.getDeclaredFields();获得当前类以及超类指定的publicField:–Fieldfield=classType.getField(Stringname);获得当前类申明的指定的Field:–Fieldfield=classType.getDeclaredField(Stringname);通过反射动态设定Field的值:–fieldType.set(Objectobj,Objectvalue);通过反射动态获取Field的值:–Objectobj=fieldType.get(Objectobj);2010-12-2第16页成都天府软件园有限公司TOSC-ITOn案例四:动态操纵Field2010-12-2第17页成都天府软件园有限公司TOSC-ITOn案例五:趁热打铁(提出问题)在Hibernate中,已知有一个user实体(属性id,name,phone)需要被update,我们通常有三种方式:①首先UserloadUser=session.load(user.getId);此时loadUser是持久化的,然后使用loadUser.setX(user.getX)方法把需要更新的字段set一下②写hql语句③session.update(user);问题来了:假如user实体中只有id和name有值,如果我们用以上方式更新的话,phone因为是null,数据库的phone本来是有值的,但经过更新后,也会被更新成null。那么有什么方法能判断user实体中哪些对象为null呢?然后我们就可以不更新那些字段。也许反射可以帮忙解决。2010-12-2第18页成都天府软件园有限公司TOSC-ITOn案例五:趁热打铁(分析问题)已知有一个user实体(属性id,name,phone)需要被update我们的解决方式其实很简单:首先UserloadUser=session.load(user.getId);此时loadUser是持久化的然后使用loadUser.setXXX(user.getXXX)方法把需要更新的字段set一下至于怎么判断哪些属性需要更新,我们可以通过反射先获得所有的getXXX方法,然后逐个invoke获得它们的值,判断一下如果值需要更新才执行loadUser.setXX(user.getXXX)2010-12-2第19页成都天府软件园有限公司TOSC-ITOn案例五:趁热打铁(解决问题)看源码:2010-12-2第20页成都天府软件园有限公司TOSC-ITOnSpring框架的IOC的简化实现2010-12-2第21页成都天府软件园有限公司TOSC-ITOnJava反射总结只要用到反射,先获得ClassObject没有方法能获得当前类的超类的private方法和属性,你必须通过getSuperclass()找到超类以后再去尝试获得通常情况即使是当前类,private属性或方法也是不能访问的,你需要设置压制权限setAccessible(true)来取得private的访问权。但说实话,这已经破坏了面向对象的规则,所以除非万不得已,请尽量少用。Array对象并未讲解,请下来自己学习。2010-12-2第22页成都天府软件园有限公司TOSC-ITOnHomework通过反射找出java.lang.Math这个类的构造函数、属性和方法。作业提交期限:2010年12月31日2010-12-2成都天府软件园有限公司TOSC-ITO第23页Theend
本文标题:Java反射机制.
链接地址:https://www.777doc.com/doc-2880760 .html