背景:
我不相信你会问—啥是框架? (简单理解为可复用的代码)像现在很流行的框架如 Spring , Spring boot,Spring AOC 等都是框架,组成它们的代码中总会见到反射机制。
简介:
反射: 将类的组成部分封装成一个对象。
用一张图解释哈:
过程解释:
还是一个老生常谈的问题,我们用高级语言编写的代码如何被计算机执行? 都知道计算机只能执行机器码。 所以我们编译高级语言代码最终也会生成机器码,只不过中间有一个过度的部分那就是字节码。利用 javac 生成字节码后,我们想执行这个程序。又知道计算机是从内存中读取指令和数据的,我们利用反射将字节码文件加载进内存,然后被计算机所执行。
使用反射的好处:
1 可以在程序运行中操纵这些对象
2 可以解耦,提高程序的可扩展性
===============================================================
应用举例:
获取 Class 对象的方式(可以理解 Class 对象是反射的另一种体现):
1 Class.forName("全类名") // 将磁盘中的对应代码加载进内存,返回 Class 对象(**多用于配制文件)
2 类名.class //通过类名的属性获取对象(内存中),(**多用于参数传递)
3 对象.getclass() // getclass()在Object对象中定义着(**多用于对象获取字节码的方式)
//结论
同一个字节码文件(*.class)在一次程序运行中只会被加载一次进内存,不论通过那种方式获取 Class 都是代指同一个对象
Class 对象的功能:
// 获取内存中的成员变量们
- cls.getFileds(); // 获取 public 修饰的成员变量
- cls.getFiled(String name); // 获取指定 public 修饰的成员变量
- cls.getDeclaredFileds(); // 获取全部成员变量(忽略修饰符)
- cls.getDeclaredFiled(String name); // 获取指定成员变量(忽略修饰符)
注:获取 private 修饰的变量后想给其赋值必须先执行能忽略修饰符的代码-->
- cls.setAccessible(True);
// 获取内存中的构造方法们
- cls.getConstructor(String.class,int.class); // 获取指定 public 修饰的构造方法
- cls.getConstructors(); // 获取 public 修饰的构造方法
- cls.getDeclaredConstructor(String.class,int.class);// 获取指定 public 修饰的构造方法(忽略修饰符)
- cls.getDeclaredConstructors(); // // 获取构造方法(忽略修饰符)
获取构造方法有啥用呢??? 哈哈,当然是创建对象啦。
Constructor c = cls.getConstructor(String.class,int.class);
Object o = c.newInstance("ss",70);
// 获取成员方法也是相似的代码(这里就忽略了)
我想看到这里你还是对反射的作用记忆不深刻,也不知道用它来获取对象和获取对应的方法并执行有啥用? 如果你有这个疑问,那么问题就来了:
问: 利用反射机制,写一个框架,可以创建任意对象,执行任意方法。
是不是没有思路??? 是不是觉得虽然知道反射但还是不会用它解决问题?如果你一上来就写代码,根据传入指定的全类名和方法名这种办法,可行是可行但耦合度太高了。
简单的处理是 配制文件+反射(在配置文件内写全类名,和指定要执行的方法名。)
/**
- 创建配置文件(后缀名一定为 .properties)
- 创建配置文件对象
- 获取配置文件
- 根据配置文件对象获取配置文件内容
- 根据内容创建对象
- 根据内容找到方法并执行
**/
Properties pro = new Properties();
//获取配置文件
InputStream in = getclass.getClassLoad().getResourceAsStream("配置文件路径")
//加载配置文件
pro.load(in);
//获取配置文件内的内容
String className = pro.getProperty("className");
String method_name = pro.getProperty("method_name");
//利用反射创建对象,执行对应方法
Class cls = class.forNmae("className"); // 加载对象进内存
Object obj = cls.newInstance(); //创建对象
Method me = cls.getMethod("method_name"); //获取指定方法
me.invoke(obj); //执行指定方法(需要对象为形参)
总结:
上面写到了一些反射的常见用法,以及在框架中如何使用反射机制,极大的简化了代码量。我希望对你有所帮助。
来源:CSDN
作者:浮夸,
链接:https://blog.csdn.net/weixin_44678969/article/details/103623888