反射(Reflect)
2016-06-15 21:04
288 查看
反射(Reflect)
Java提供的API,提供了一套动态的执行机制,可以:动态创建对象,动态访问属性,动态调用方法。。。
动态 与 静态
静态:经过编译以后就能够确定的调用关系称为静态。String s="abc"; System.out.println(s.length());
动态:在运行期间动态确定的调用关系称为动态。
使用反射API实现代码的调用。
为什么要用动态执行?什么时候必须使用动态执行?
需求:执行一个有无参数构造器的类,全部以test为开头的方法。分析:类名不清楚,不能使用new类名这种语法
不能调用方法:obj.方法()
结论:使用静态方法调用规则无法实现。
如上需求必须使用反射api动态实现。
动态创建对象
在运行期间根据一个动态的类名动态的创建对象,在运行期间根据任意的类名创建其对象。动态加载到方法区
Class.forName()方法会自动到硬盘查找className对应的*.class文件,找到以后读取验证并且加载到方法区,加载结果为方法区中的类信息(类信息包括:构造器,属性,方法等),返回一个引用,这个引用利用本身可以访问类的信息。当类名错误时候出现异常:ClassNotFound
代码示例:
Scanner scan=new Scanner(System.in);
//运行期间动态获得类名
String className=scan.nextLine();
//使用反射API动态加载类
Class cls=Class.forName(className);
System.out.println(cls);
动态创建对象的实例
1、Class API 提供了创建对象的方法-newInstance()返回创建好的对象
2、这个API要求类一定有无参数构造器
-如果没有无参数构造器,抛出无此方法异常!
3、利用这个方法可以动态创建对象。
反射API提供了哪些功能
动态加载类
Class.forName 方法加载类:先检查方法区内存中是否已经加载类,如果已经加载,就直接返回这个类信息,如果没有加载,再加载class文件到方法区。动态获取类的信息(构造器*n 属性*n 方法*n)
》查询Class类的手册 http://doc.tedu.cn- Class 提供了获取类信息的API。
- getDeclaredFields()返回类中全部的属性信息,返回的Field数组。
- Field 类封装了一个属性相关信息:修饰词,数据类型,属性名等
cls{ Field[] { Field {属性名,类型}}}
Eclipse 就是利用反射API实现了,动态显示一个对象有哪些属性。
动态显示一个类全部方法信息
使用Class提供的API getDeclaredMethods()-返回一个Method[]数组代表多个方法信息
-没Method对象封装了一个方法的信息(返回值,方法名,参数列表)
-getReturnType()返回值类型
-getName()返回方法名
-getParamterTypes()返回参数列表
-步骤
1.动态加载类
2.getDeclaredMethods()
3.for()遍历每个方法信息
-显示每个方法信息
动态显示一个类全部构造器信息
-使用Class提供的API方法获取全部构造器信息getDeclaredConstructors()-返回一个数组Constructor[]
-每个constructor元素:包含一个构造器的信息:方法名,参数列表等
-步骤
-1.动态加载类
2.调用方法getDeclaredConstructors()
3.for遍历每个构造器信息
动态创建对象
在运行期间根据一个动态的类名动态的创建对象动态调用无参数构造器创建对象
1、Class API 提供了创建对象的方法-newInstance()返回创建好的对象
2、这个API要求类一定有无参数构造器
-如果没有无参数构造器,抛出无此方法异常!
3、利用这个方法可以动态创建对象。
动态调用有参数构造器创建对象
任何类型,任何一个构造器,传递任何参数静态创建对象
ArrayList list=new ArrayList(200);
动态调用构造器:类名不知,参数不知,哪个构造器不确定。
- 使用反射API实现
- 使用Class.forName()动态加载类
- Class 的方法getDeclaredConstructor(参数类型列表),查找到一个与参数类型列表匹配的构造器,返回两种情况
-找到返回Constructor对象,构造器信息
-找不到:抛出异常,方法没有找到
-参数类型列表:
- Class类型数组,元素是Class类型
- 整数的类型:int.class
- double的类型:double.class
- String的类型:String.class
- 类型列表(int ,int ,String)new Class[]{int.class,double.class,String.class};
- 执行构造器创建对象
-Constructor类提高了newInstance(参数列表),执行的是有参数构造器。
-要求参数列表与构造器参数类型匹配。否则抛出参数类型错误异常。
-构造器执行期间出现异常,目标调用异常
-参数列表(5,8,”tom”):
- Object[]数组
- new Obect[]{5,8,”tom”};
- 返回值是一个对象
在工作中调用无参数构造器创建对象,使用频率最高:Class.newInstance();
动态访问属性
属性一定属于对象。访问对象的属性。-使用反射API访问,某对象的某个属性
-动态:对象不明,属性不知
-如何使用:
1.找到对象的Class
- Object提供了方法 getClass()返回次对象的Class信息(方法区中的信息)
2.找到属性信息:
- getDeclaredField(属性名)根据属性名找到属性信息。
3.属性信息Field类提供了访问属性的方法
- Field.get(被访问的对象)返回属性的值,理解为在对象上读取属性值
- Field.set(被访问的对象,值)设置属性的值
动态调用方法
调用某对象的某个方法,传递某些参数-使用反射API访问,某对象的某个属性
-动态:对象不明,方法不知,参数不明
-实现方法:
1- 找到Class:obj.getClass()
2- 找到被执行的方法信息Method-Class.getDeclaredMethod(方法名,参数类型列表),返回对应的方法信息
3- 执行Method信息类的Invoke()方法
-Method.invoke(参数列表)返回值是方法执行的结果。
实现一个经典案例:动态调用test方法
必须使用反射实现:1.类型不明
2.方法不明
做法:
1.动态加载类
2.动态创建对象(无参)
3.找到全部的方法
- 遍历,检查哪个方法以test开头,而且方法参数类型的长度是0:找到以test为开头的参数方法。
4.执行这个方法,method.invoke()
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树