Reflection In Java
Reflection
反射(Reflection)允许程序在运行时检查和修改自身的结构和行为。通过反射,程序可以动态地获取类的详细信息,包括类的成员变量、方法、构造器等,并可以在运行时调用这些成员。
这种能力使得 Java 在某种程度上具有了动态语言的特性。Spring/Spring Boot、MyBatis 等框架以及 Java 注解均大量应用了反射机制。此外,在使用 IDE 进行开发时,当输入一个对象或类后按下.
,IDE 会自动列出该对象或类的所有可用属性和方法。这一功能背后也是通过反射机制实现的
java.lang.reflect
包中提供了 reflection API,使用反射,可以在 runtime 期间进行以下操作:
- 判断任意一个对象所属的类
- 构造任意一个类的对象
- 判断任意一个类所具有的成员变量和方法
- 获取泛型信息
- 调用任意一个对象的成员变量和方法
- 处理注解
- 生成动态代理
反射相关 API
java.lang.Class
: 代表一个类java.lang.reflect.Method
: 代表类的方法java.lang.reflect.Field
: 代表类的成员变量java.lang.reflect.Constructor
: 代表类的构造器
Runtime Class
java.lang.Class<T>
表示正在运行的 Java 应用程序中的类和接口
当 Java 程序启动时,类加载器(class loader)负责将 .class 文件中的字节码加载到内存中。
加载过程中,虚拟机会为被使用的 class 创建一个类型为 java.lang.Class
的实例(Instance),用于表示该类,一般称这个类为 runtime class
Syntax
使用反射获取构造器并创建实例
Usage Example
八股
反射机制的优缺点
优点:
- 能够运行时动态获取类的实例,提高灵活性;
- 与动态编译结合
缺点:
- 使用反射性能较低,需要解析字节码,将内存中的对象进行解析。 解决方案:
- 通过 setAccessible(true)关闭 JDK 的安全检查来提升反射速度;
- 多次创建一个类的实例时,有缓存会快很多
- ReflectASM 工具类,通过字节码生成的方式加快反射速度
- 相对不安全,破坏了封装性(因为通过反射可以获得私有方法和属性)
Reflection In Java