黑马程序员技术交流社区
标题: 【哈尔滨校区】关于反射的一些小结 [打印本页]
作者: 张斯佳 时间: 2018-3-13 14:00
标题: 【哈尔滨校区】关于反射的一些小结
反射
在JAVA框架的底层,大量运用了反射技术,能够让我们更好的理解一些技术的底层。因此,了解和运用反射是很有必要的!
它的作用就是能在系统需要的,合适的时候,更快速的创建对象,获得方法。而不是在系统运行的初始就创建所有需要的对象。能够高系统的运行速度和效率。
那么什么是反射机制呢?
反射机制是在运行时,我们可以获取任意一个类的所有方法和属性,并且可以调用任意一个对象的所有方法和属性。
简单来说, 就可以把.class文件比做动物的尸体, 而反射技术就是对尸体的一种解剖.
通过反射技术, 我们可以拿到该字节码文件中所有的东西, 例如成员变量, 成员方法, 构造方法, 而且还包括私有。
反射的前提:
要获取类的对象(Class对象,字节码对象)
1.1.2字节码文件获取的三种方式
1.对象名.getCalss() 此方法来自于Object 对象已经存在的情况下, 可以使用这种方式
2.类名.class 类名.class这是一个静态的属性, 只要知道类名, 就可以获取
3.Class.forName(“com.itheima_01.Student”) 通过Class类中的静态方法, 指定字符串, 该字符串是类的全类名(包名+类名)
此处将会抛出异常都系 ClassNotFoundException 防止传入错误的类名
反射操作构造方法 :
步骤:
1.获得Class对象
2获得构造
3.通过构造对象获得实例化对象
通过反射获取构造方法并使用
1.Constructor<?>[]getConstructors()
2.Constructor<T>getConstructor(Class<?>... parameterTypes)
3.TnewInstance()
例:
Constructorc =clazz.getConstructor(String.class,int.class) 获取有参构造,参数1类型为String,参数2类型为int
Constructorc =clazz.getConstructor();//获取无参构造
Constructor[]cs = clazz.getConstructors()
直接通过Class类中的newInstance()和获取getConstructor()有什么区别?
newInstance()方法, 只能通过空参的构造方法创建对象
getConstructor(Class<T>…parameterTypes)方法, 方法接受一个可变参数, 可以根据传入的类型来匹配对应的构造方法
总结
Constructor<?>[]getConstructors()
Constructor<T>getConstructor(Class<?>... parameterTypes)
方法1: 获取该类中所有的构造方法,返回的是一个数组
方法2: 方法接受一个可变参数, 可以根据传入的类型, 来匹配对应的构造方法
通过反射运行public变量流程
1.通过反射获取该类的字节码对象
Classclazz = Class.forName("com.heima.Person");
2.创建该类对象
Objectp = clazz.newInstance();
3.获取该类中需要操作的字段(成员变量)
getField(Stringname) --> 方法传入字段的名称.
注意: 此方法只能获取公共的字段
Fieldf = clazz.getField("age");
4.通过字段对象中的方法修改属性值
voidset(Object obj, Object value) --> 参数1): 要修改那个对象中的字段, 参数2): 将字段修改为什么值.
f.set(p,23);
通过反射获取成员方法并使用
反射获取普通成员方法
反射public方法执行流程
1. 获取学生类字节码对象
2. 反射手段创建学生对象
3. 调用getMethod方法获取Method对象, 方法形参接受方法的名字
4. 调用Method方法中的invoke()将方法运行
私有的成员方法怎么获取,这就需要用暴力反射来获取方法:
获取字节码对象
Classclazz = Class.forName("com.heima.Student");
创建学生对象
Objectstu = clazz.newInstance();
暴力反射获取方法
Methodmethod = clazz.getDeclaredMethod("method");
让jvm不检查权限
method.setAccessible(true);
执行方法
method.invoke(stu);
反射操作私有成员变量
反射private成员变量(字段)
反射private属性执行流程
1. 获取学生类字节码对象
2. 获取学生对象
3. 通过getDeclaredField方法获取私有字段
4. 通过setAccessible让jvm不检查权限
5. 通过set方法设置对象为具体的值
工具类:javaBean和BeanUtils
javaBean:将需要操作的多个属性封装成JavaBean,简单来说就是用于封装数据的
步骤:
类使用公共进行修饰
提供私有修饰的成员变量
为成员变量提供公共getter和setter方法
提供公共无参的构造
实现序列号接口
BeanUtils:
使用BeanUtils能够更快捷的运用反射来获取方法和更改属性,很好的提高我们在编写代码时的效率。
BeanUtils的常用方法:
setProperty 用来给对象中的属性赋值(了解)
参数1: 需要设置属性的对象
参数2: 需要修改的属性名称
参数3: 需要修改的具体元素
getProperty用来获取对象中的属性(了解)
参数1: 要获取的javaBean对象
参数2: 对象中的哪个属性
Populate用来给对象中的属性赋值(掌握)
参数1: 要设置属性的对象
参数2: 将属性以Map集合的形式传入
Key: 属性的名称
Value: 属性具体的值
作者: xutian4500 时间: 2018-3-16 13:36


欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |