一、什么是反射?
反射是Java最经常用到的基础知识,但是也是比较难理解的一点。今天就来好好说说他。
根据反射的普遍解释就是:在Java运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。对于任意一个对象,可以调用它的任意一个方法。这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制
简言之,反射(Reflection)就是在Java运行时,动态获取类(class)的信息以及动态调用对象(Object)的方法的功能。
反射的优缺点:
优点就是动态创建对象和编译,灵活性高。
反射的缺点就是对性能有些影响。(缺点实际上由于现在JVM的性能提高,和在开发时有一些编辑是可控的可以降低对性能的影响)
二、反射的主要用途
spring管理着bean组件,简单来说省去了庞杂的new来调取对象。这就是我们最长接触到的反射机制。原来EJB就是通过new这种方式来调用对象:
而spring运用反射则将原来的这种方式直接配置到一个配置文件中来避免ejb对象的频繁调用和解耦。
可以从内存角度去理解反射,也可以从我反射的定义去理解它。即当我们平时“引入类的名称->通过new实例化->取得实例化对象”的过程。使用反射就可以变成“实例化对象->getClass()方法->得到完整的类名称”这样的过程。
反射机制主要提供了4个功能:
1、在运行时判断任意一个对象所属的类
2、在运行时构造任意一个类的对象
3、在运行时判断任意一个类所具有的成员变量
4、在运行时调用任意一个对象的方法
Java反射机制常用到4个类:Class,Construct,Field,Method,
其中Construct,Field,Method是属于Java.lang.refleact包下,releact包主要就是提供反射的API,Class类则获取一个要操作的类的对象,该对象属于java.lang.object包,该对象代表一个正在运行的一个类或接口。下图是jdk源码,各类所在的位置:
二、反射的分析
首先,从内存角度分析反射。这里引用个经常出现的内存资料图片:
由图可知,运行时JVM的内存结构。我们平时用IDE开发时候的.Java先编译成.class文件,然后被类加载器加载到JVM中。然后被类加载器加载进jvm的内存中,此时类Object加载到方法区中,创建了Object类的class对象到堆中,注意这个不是new出来的对象,而是类的类型对象,每个类只有一个Class对象,作为方法区类的数据结构的接口。jvm创建对象前,会先检查类是否加载,寻找类对应的Class对象,若加载好,则为你的对象分配内存,初始化也就是new 。
![]()
内存角度的分析这里引用了知乎,作者:老顽童周伯通 的观点和讲解。链接:https://www.zhihu.com/question/24304289/answer/147529485