【Java初学基础10】一文讲清反射
1. 什么是反射
反射(Reflection)是 Java 提供的一种在运行时动态获取类的信息,并能操作类的属性和方法的机制。
通过反射,你可以在不知道对象具体类型的情况下,操作它的属性、方法、构造函数等。
使用idea时的自动提示就是依赖了反射机制。
反射的核心是 java.lang.reflect
包。
字节码文件的本质
class
文件是 跨平台的中间表示形式,里面存放着:
类的元信息(类名、父类、接口等)
成员变量信息
方法的字节码指令
常量池(字符串常量、方法引用等)
我们可以通过反射获取这些信息。
所以 Java 实现了“一次编译,到处运行”:
Windows、Linux、Mac 各自有 JVM,能识别同样的
.class
文件并执行。
2. 反射的主要功能
获取类的字节码信息
Class<?> clazz = Class.forName("java.util.ArrayList");三种获取方式:Class.forName("全限定类名")类名.class对象.getClass()
获取类的信息
类名:
clazz.getName()
、clazz.getSimpleName()
包名:
clazz.getPackage()
获取构造方法
Constructor<?>[] constructors = clazz.getConstructors(); // 公共构造方法 Constructor<?> constructor = clazz.getDeclaredConstructor(String.class); // 指定构造器
getConstructors() 获取 所有 public 构造方法。getDeclaredConstructors() 获取 所有构造方法(包括 private、protected、default、public)。getConstructor(Class<?>... parameterTypes) 获取 指定参数类型的 public 构造方法。getDeclaredConstructor(Class<?>... parameterTypes) 获取 指定参数类型的构造方法(不管访问修饰符)。
获取字段(成员变量)
Field[] fields = clazz.getDeclaredFields(); // 所有字段 Field field = clazz.getDeclaredField("name"); field.setAccessible(true); // 允许访问 private field.set(obj, "Tom"); // 给字段赋值
获取方法
Method[] methods = clazz.getDeclaredMethods(); Method method = clazz.getDeclaredMethod("setName", String.class);method.invoke(obj, "Tom"); // 调用方法
操作对象
Object obj = clazz.getDeclaredConstructor().newInstance(); // 创建对象
总结:
public 构造方法:用
getConstructors()
或getConstructor(...)
。所有构造方法(包括 private):用
getDeclaredConstructors()
或getDeclaredConstructor(...)
,并且要setAccessible(true)
才能使用。(暴力反射,不管是不是private)获取成员变量:
getField
→ public 字段(含继承)getDeclaredField
→ 本类所有字段(private/protected/public/默认)
操作 private 字段:
setAccessible(true)
获取/修改值:
get(obj)
/set(obj, value)
反射可以获取字段名、类型、注解信息等,非常灵活,但性能比直接访问慢一些。
反射的应用场景
应用方向 | 案例 | 技术体现 |
---|
动态类加载 | 插件系统、工厂模式 | Class.forName() + newInstance() |
动态方法调用 | MVC 框架、测试工具 | Method.invoke() |
动态字段访问 | ORM 框架、JSON 序列化 | Field.get()/set() |
注解解析 | Spring、JUnit | isAnnotationPresent() , 反射扫描类/方法 |
动态代理 | AOP、RPC | Proxy.newProxyInstance() |
配置驱动 | 任务调度、自动化脚本 | 结合反射解析配置执行类/方法 |
✅ 核心结论:
反射的最大价值是 通用性和灵活性,它允许程序在运行时动态处理类、对象和方法,解耦、框架化、插件化、自动化。