反射 在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: 属性具体的值
|