想要了解反射,首先得先了解下一J V M 类 加 载 流 程 和 内 存 结 构,如下图。
java源文件通过编译器加载成Class文件(包含类所有信息),然后通过ClassLoader将Class文件加载到JVM中,在内存中进行管理。
而反射就是获取这个Class文件,从而获取到类的属性,类的方法,类的字段,实现的接口等等。
我们通过下图来感受一下反射与new对象之间的区别:
new对象和反射在类加载上的区别是:new对象(RTTI)是在编译期打开和检查Class文件。而反射是在运行期打开和检查Class文件。
因次我们不难理解我们在编写业务代码时使用new对象居多,而我们所使用框架底层是使用反射居多。
这是因为当我们能够在编译期能够确定使用的对象时就使用new,而当我们在编译期间不能确定所使用的对象时,就使用反射(在运行期间将用到的对象给反射出来)。
下面,我通过伪代码给大家介绍反射的使用:
三种获得Class文件的方式:
// 方式一 类.class
Class personClazz = Person.class;
// 方式二 实例.getClass()
Person person = new Person();
Class personClazz1 = person.getClass();
// 方式三 Class.forName("类的全路径")
Class personClazz2 = Class.forName("com.muse.reflect.Person");
//大家来回答一下下面两个返回的是true还是false
System.out.println(personClazz == personClazz1);
System.out.println(personClazz == personClazz2);
复制代码
答案是两个都是true(同一个对象的class文件只有一个)
通过Class对象,创建构造方法对象:
//初始化无参构造方法
Constructor constructor = personClazz.getConstructor();
// 初始化有参构造方法对象
Constructor constructor1 = personClazz.getConstructor(String.class, Integer.class, Byte.class,Boolean.class);
复制代码
通过构造方法创建对象:
// 调用无参数构造方法创建Person对象
Person person = (Person) constructor.newInstance();
// 调用有参数构造方法创建Person对象
Person person1 = (Person) constructor1.newInstance("无尽的蓝海", 2021, (byte) 1, true);
复制代码
本篇文章到此结束,没有讲完的获取成员方法,获取成员属性,还有反射的应用打算留到下一篇文章再分享了。(主要是因为写到一半,发现要伪代码的方式后面有点不太好讲。于是打算先停一下,思索一下用什么方式可以让大家有更好的观看体验)