反射
java代码在计算机中经历的三个阶段
第一阶段:Source源代码阶段 将java代码编译成.class字节码文件
第二阶段:class类对象阶段通过java中的ClassLoader(类加载器)将class文件放入内存,并为之创建除一个Class对象 所有的同类型的对象共享一个Class对象包括基本数据类型
第三阶段:Runtime运行时阶段
Class
没有公共构造方法。Class
对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass
方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。
反射的作用
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wgjcZPCa-1636189285957)(C:/Users/HUAWEI/AppData/Roaming/Typora/typora-user-images/image-20211105204234593.png)]
如idea编译器运行过程中,可以操作这些对象
-
可以解耦,提高程序的可扩展性
获取Class对象的方式
- Class.forName(“全类名”):将类加载进内存然后返回Class类(多用于配置文件,将类名定义在配置文件中,读取文件,加载类)
- 类名.class:通过类名的属性来获取Class类(多用于参数的传递)
- 对象.getClass():通过实例对象的getClass()方法来获取Class对象(多用对象的获取字节码文件)
Class对象功能:
获取功能
- 获取成员变量们
- Field[] getFields()//获取所有public修饰的成员变量
- Field getField(String name)
- Field [] getDecareFields()
- Field getDeclareFiedl(String name)
- 获取构造方法们
- Constructor<?>[] getConstrructors()
- Constructor getConstructor<Class <?>…parameterTypes>
- Constructor getDeclaredConstructor<类<?>…parameterTypes>
- Constructor<?> [] getDeclaredConstructors()
- 获取成员方法们:
- Method[] getMethods()
- Method getMethode(String name,Class<?>…parameterTypes)
- Method getDeclaredMethods()
- Method getDeclaredMethod(String name,Class<?>…parameterTypes)
- 获取类名
- String getName()
-
Field:成员变量
-
操作
- 设置值
- void set(Object obj,Object value)
- 设置值
- void get(Object obj)
- 设置访问权限
- setAccessible(true)//忽略访问修饰符的安全检测 暴力反射
- 设置值
-
Constructor:构造方法
- 创建对象
- T newInstance(Objcet…initargs)
- 如果使用空参构造方法创建对象时,操作可以简化:Class对象的newInstance方法
Method:方法
- 操作
- 获取方法
- Method getMethod(String name,Object…args)//方法名 加上参数列表的Class
- 调用方法
- Object invoke(Objcet obj,Object…args)//指定参数并且调用方
- 获取方法
反射的一个小案例
需求:##### 写一个"框架",不能改变类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中的任意方法
- 实现
-
- 配置文件
- 反射
-
- 步骤
-
- 将需求创建的对象的全类名和需要执行的方法定义在配置文件中
- 在程序中加载读取配置文件
- 使用反射技术来加载类文件进内存
- 创建对象
- 执行方法
-
package javaweb; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Properties; public class ReflectTest { public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { //1.加载配置文件 //1.1创建Properties对象 Properties pro = new Properties(); //1.2加载配置文件,转换为一个集合 //1.2.1获取class目录下的配置文件 ClassLoader classLoader = ReflectTest.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream("pro.properties");//获取资源文件返回其字节流 pro.load(is); //2.获取配置文件的中定义的数据 String className = pro.getProperty("className"); String methodName = pro.getProperty("methodName"); //3.加载改类的进内存 Class cls = Class.forName(className); //4创建对象 Object obj = cls.newInstance(); //5.获取方法对象 Method method=cls.getMethod(methodName); method.invoke(obj); } }