反射:框架的设计灵魂
-
框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
在了解反射的概念之前,要先了解java代码在计算机中经历的三个阶段,如下图
-
反射:将类的各各组成部分封装成为其他对象,这就是反射机制
如上图中所示,将成员变量name、age封装成Field对象;将构造方法封装成为Constructor对象;将成员方法封装成为Method对象,这就是反射机制-
好处:
-
可以在程序的运行过程中去操纵这些对象,如下所示:
String str后面跳出来许多可用的方法,这就是上图中
-
可以解耦,提高程序的可扩展性
-
-
-
获取Class对象的方式
-
Class.forName(“全类名”); :将字节码文件加载进内存
全类名,就是写类名时还要包含包的名字
- 多用于配置文件,最后的案例就是一个示例
-
类名.Class:通过类名的属性class获取
在Class类对象阶段使用
- 多用于参数的传递
-
对象.getClass():getClass()方法在Object类中定义
- 多用于对象的获取字节码的方式
-
- 结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,无论通过哪一种方式获取的Class对象都是同一个
-
Class对象功能:
- 获取功能:
- 获取成员变量们
-
Field[] getFields():获取所有public修饰的成员变量
-
Field getField(String name):获取制定名称的public修饰的成员变量
-
Field[] getDeclaredFields()
-
Field getDeclaredField(String name)
-
- 获取构造方法们
- Constructor<?>[] getConstructors();
- Constructor getConstructor(类<?>… parameterTypes)
- Constructor<?>[] getDeclaredConstructors();
- Constructor getDeclaredConstructor(类<?>… parameterTypes)
- 获取成员方法们
- Method[] getMethods()
- Method getMethod(String name,类<?>… parameterTypes)
- Method[] getDeclaredMethods()
- Method getDeclaredMethod(String name,类<?>… parameterTypes)
- 获取类名
- String getName()
- 获取成员变量们
- 获取功能:
-
Field:成员变量
-
操作
-
设置值
- get(Object obj)
-
获取值
- set(Object obj)
-
忽略访问权限修饰符的检查
- setAccessible(true)
-
-
-
Constructor:构造方法
-
创建对象:
-
T newInstance(Object… initargs)
-
如果使用空参数的构造方法创建对象,操作可以简化:Class对象的newInstance方法
-
-
-
Method:方法对象
-
执行方法:
- Object invoke(Object obj,Object… args)
-
获取方法名称
- String getName();
-
-
案例:
-
需求:写一个“框架”,在不改变任何代码的前提下,可以帮助我们创建任意类的对象,并且执行其中任意方法
-
实现:
- 配置文件
- 反射
-
步骤
- 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
- 在程序中加载配置文件
- 使用反射技术来加载文件进入内存
- 创建对象
- 执行方法
package top.faroz.reflect; import top.faroz.domain.Person; import top.faroz.domain.Student; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.util.Properties; /** * @ClassName ReflectTest * @Description 反射的实操 * @Author FARO_Z * @Date 2020/8/15 12:45 上午 * @Version 1.0 **/ public class ReflectTest { public static void main(String[] args) throws Exception { /** * 可以创建任意类的对象,可以执行任意方法 * 前提:不能改变该类的任何代码,可以创建任意类的对象,可以执行任意方法 * 比如说下面这段代码 */ // Person person = new Person(); // person.eat(); // // Student student = new Student(); // student.sleep(); /** * 对不同的对象进行新建、调用方法,每次都要写新的代码,不符合上述的要求 * 但是,反射可以解决以上问题 */ //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); //6.执行方法 method.invoke(obj); } }
-
-