最近,我想复习反射了解背后的原理,发现这水比我想象的要深得多,反射的伟大之处。 Reflect实际上是Class对象操作的高手,稍后会进行分析。
1 .反射介绍
Java正在运行(运行时) :
获取任何类的方法和属性,并实例化对象;
处理任何对象的方法和属性
事实上,从JDK的第一个版本开始就支持评论,通过三种方式实现反射。 (目前,由于场景通用性强,例如在jdbc中部署数据库驱动程序,因此第三个非常常用。)
//第一个:在Object类的getClass方法中
Class cla=foo.getClass (;
//第二个:通过对象实例的方法获取对象
Class cla=foo.class;
//第三个:以Class.forName方式
class cla=class.forname (xx.xx.foo );
2 .什么技术支撑着反射
我试图直接分析反射的原理,但发现其实在逻辑上不合理。 我们试图改变视角,从java为什么是静态语言来分析反射。
结论1:Java是静态语言,编译时需要进行类型检查。
动态语言:类型检查在运行时进行
静态语言:类型检查在执行前判断(编译阶段) )
类a {
公共void DOA () {
system.out.println('doa );
}
}
类b扩展a {
公共void DOB () {
system.out.println(dob );
}
}
(b ) new A ) ).doB );
上述代码已编译,但运行报告错误。
为了支持多态性,Java是确保在运行时实际运行的对象类型
Java需要确定在运行时实际运行的对象类型。 也称为“动态绑定”。
结论2 :继承、多态性需要动态绑定。
请注意,这里的动态绑定是确定Java引用的对象的实际类型,并根据该实际类型调用相应的方法。
虽然听起来有点空虚,但我来说明:
对于下面的话,你怎么知道是父亲的话还是儿子的话?
//继承或多态性
公共内置执行(father reference ) {
reference.talk (;
}
Father f=new Son (;
Father f2=new Father (;
exec(f;
exec(F2;
上述情景如何知道JVM是Father.taslk )还是Son.talk )?
因此,在编译时,默认的Father.talk ()会通过默认的编译直接由父亲说话(在编译时为默认的父类)。
但是,在运行时,它在当前线程堆栈中找到对象引用f的真正内存地址,地址指向堆。 由于此对象实例位于堆中,且对象实例包含Class信息,因此可以返回到方法区域,查找与此对象对应的Class对象,然后在Class对象中找到方法表当子类重写父类的方法表时,它始终指向子类的方法代码块。 这就是动态绑定的概念。 因此,无论是多态性还是继承,只要确保实际对象的方法调用正确,就不会错误地调用java。
(JDK1.6或更低版本: Class对象位于方法区域,JDK1.6或更高版本位于堆中)
image.png
红线是动态绑定的过程,而黑线是APP应用程序开始加载Class对象的过程
继承、多态性都需要动态绑定支持。
Java是静态语言,但它是专门添加的动态语言特性,以支持各种面向对象的特性。
结论)动态绑定需要方法区域的Class对象,也称为RTTI。
运行时间类型信息(RTI )意味着Java可以在运行时获取或确定对象的类型信息。
将基于方法区域中的Class对象实现RTI,并且获取或判断一个对象的类型信息源于Class对象。
现在网上很多理解的结论都是错误的,但方向是正确的。 RTTI机制分为传统的RTTI和反射两种。
RTI的核心不是形式,两者的区别只是如何操作Class对象,应该从操作方式上加以区分
传统的RTTI :继承、多态和强旋转是依赖于已经存在的对象实例获得其中的Class对象。
反射:除了从已存在的对象实例中检索类对象外,还可以直接从名称到方法区域直接搜索类对象。
比较分析如下
image.png
传统的RTTI与反射相比:
传统的RTTI需要对象实例。
这意味着需要Class对象。
对于这个班
有正确的引用。↓
意味着编译期该类文件存在且编译通过。
以上种种,反射可以都不需要!(类文件不存在也行,要用的时候才会报错)
结论4:RTTI机制支撑着反射
回过头来看反射的三种实现方式,统统都是需要Class对象支撑的,也就是RTTI机制。
RTTI机制的引入为Java这种静态语言带来了动态语言的特性,在不改变整体设计的情况下,提升了代码抽象能力和灵活性。
一般不要认为Java的反射就是指java.lang.reflect,这个包提供的工具类和接口。其实Java的整个Class对象系统,包括所有类的始祖类Object类,基础类型以及每个对象都附带的Class对象,都是反射机制的一部分。Java最初在设计这个系统的时候就有很深的预谋,反射可以调动着Java核心资源Class对象。
反射的原理
总结反射原理
当我们编写完一个Java项目之后,每个.java文件都会被编译成一个.class文件,这些文件承载了这个类的所有信息,包括父类、接口、构造函数、方法、属性等。
这些Class文件在程序运行时会被ClassLoader加载到虚拟机中,Java虚拟机就会在内存中自动产生一个Class对象。
我们通过new的形式创建对象实际上就是通过这些Class对象来创建,只是这个过程对于我们是不透明的而已。
反射的工作原理就是借助Class.java、Constructor.java、Method.java、Field.java这四个类在程序运行时动态访问和修改任何类的行为和状态。