一.反射基础
二.反射的作用
三.反射机制执行的流程
一.反射基础什么是反射?
反射使 java 代码可以发现有关已加载类的字段,方法和构造函数的信息,并在安全性限制内使用反射对这些字段,方法和构造函数进行操作。
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD 、OpenC 、MetaXa和OpenJava等就是基于反射机制的语言。最近,反射机制也被应用到了视窗系统、操作系统和文件系统中。
Java中,反射是一种强大的工具。它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。反射允许我们在编写与执行时,使我们的程序代码能够接入装载到jvm中的类的内部信息,而不是源代码中选定的类协作的代码。这使反射成为构建灵活的应用的主要工具。但需注意的是:如果使用不当,反射的成本很高。
简而言之,指在 Java 程序运行时
- 给定的一个类(Class)对象,通过反射获取这个类(Class)对象的所有成员结构。
- 给定的一个具体的对象,能够动态地调用它的方法及对任意属性值进行获取和赋值。
这种动态获取类的内容,创建对象、以及动态调用对象的方法及操作属性的机制为反射。即使该对象的类型在编译期间是未知,该类的 .class 文件不存在,也可以通过反射直接创建对象。
优势
- 增加程序的灵活性,避免将固有的逻辑程序写死到代码里
- 代码简洁,可读性强,可提高代码的复用率
劣势
- 相较直接调用,在量大的情景下反射性能下降
- 存在一些内部暴露和安全隐患
为什么要有反射
有了反射,我们可以做以下事情:
- 在运行时检查一个对象
- 在运行时,根据一个class构造一个对象
- 在运行时,检查一个对象的属性和方法
- 在运行时,调用一个对象的任意一个方法
- 在运行时,改变对象的构造函数,属性,方法的可见性等等
反射是很多框架的共有的方法:
- 例如JUnit,就是使用反射去找出那些带有@Test注解的方法,然后就利用反射在单元测试中调用这些方法
- 在web框架中,开发人员将他们定义实现的接口和类放到配置文件中,使用反射,他可以动态地在运行时自动初始化这些类和接口 例如,Spring中一般这样使用配置文件:
<bean id="someID" class="com.programcreek.Foo">
<property name="someField" value="someValue" /></bean>
当Spring读取到bean文件的时候,会调用Class.forName(String)方法"com.programcreek.Foo"来初始化这个类,然后在使用反射正确的get到所配置的属性的set方法,并把相应的值set进去。
servlet web 也是使用这种反射技术:
<servlet>
<servlet-name>someServlet</servlet-name>
<servlet-class>com.programcreek.WhyReflectionServlet</servlet-class><servlet>
反射的原理(类加载)
关于类加载机制,大家可以参考我的这篇文章:
深入理解JVM虚拟机——类的加载机制
深入理解JVM虚拟机——JVM是如何实现反射的?
类加载机制流程
类的加载
反射的原理图解
二. 反射的作用一个类的成员包括以下三种:域信息、构造器信息、方法信息。而反射则可以在运行时动态获取到这些信息,在使用反射时,我们常用的类有以下五种。