深入理解 Java 反射机制
深入理解 Java 反射机制一、什么是 Java 反射机制核心定义Java 反射Reflection是 Java 语言内置的动态特性程序在运行阶段可以获取任意类的全部内部结构构造方法、成员变量、成员方法、注解、父类、接口等并且动态创建对象、读写属性、调用方法哪怕编译期并不知道这个类的具体名称。正向调用 vs 反射反向调用普通正向使用new 方式编译期就确定类名直接new创建对象调用属性方法属于静态编码java运行Student stu new Student();stu.setName(“张三”);stu.show();反射反向操作编译期不知道类信息运行时通过Class对象反向解析类结构动态完成对象创建、方法调用具备极强灵活性。二、反射底层原理Java 类被 JVM 加载后会在方法区生成唯一对应的Class对象这个对象封装了当前类所有元数据变量、方法、构造器、修饰符等。反射本质就是通过这个Class入口对象借助java.lang.reflect包下 API逆向读取、操作类内部信息。每个类在整个 JVM 中只会生成一个Class实例。三、获取 Class 对象的 3 种方式反射入口java运行// 方式1类名.class 编译期已知类Class clazz1 Student.class;// 方式2对象.getClass() 已有实例对象Student stu new Student();Class clazz2 stu.getClass();// 方式3Class.forName(“全类名”) 最常用配置文件读取类名、框架底层Class clazz3 Class.forName(“com.demo.Student”);四、反射核心 APIjava.lang.reflect 包表格类 作用Class 反射总入口代表类本身获取构造、方法、字段对象Constructor 操作构造方法反射创建实例对象Field 操作成员变量获取 / 修改属性值可突破 private 权限Method 操作成员方法动态执行对象方法完整反射示例代码准备实体类 Studentjava运行public class Student {// 私有成员变量private String name;public Integer age;// 无参构造public Student(){}// 私有有参构造private Student(String name){this.name name;}// 私有方法private void study(String course){System.out.println(name “正在学习” course);}// 公共方法public void showInfo(){System.out.println(“姓名”name“年龄”age);}}反射测试代码java运行import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ReflectTest {public static void main(String[] args) throws Exception {// 1. 获取Class对象Class? clazz Class.forName(“com.demo.Student”);// 2. 反射创建对象调用无参构造 Object stuObj clazz.newInstance(); // 3. 操作公有成员变量age Field ageField clazz.getField(age); ageField.set(stuObj, 18); // 4. 突破私有权限操作私有成员变量name Field nameField clazz.getDeclaredField(name); nameField.setAccessible(true); // 关闭权限校验暴力访问private nameField.set(stuObj, 李四); // 5. 调用公有方法showInfo Method showMethod clazz.getDeclaredMethod(showInfo); showMethod.invoke(stuObj); // 6. 调用私有带参方法study Method studyMethod clazz.getDeclaredMethod(study, String.class); studyMethod.setAccessible(true); studyMethod.invoke(stuObj, Java反射); // 7. 调用私有构造方法创建对象 Constructor? priCon clazz.getDeclaredConstructor(String.class); priCon.setAccessible(true); Object stu2 priCon.newInstance(王五); }}五、反射优缺点✅ 优点高度灵活性运行时动态适配类大量框架依靠反射实现配置解耦无需修改源码即可切换类。扩展性极强配合配置文件、注解实现插件式开发。框架底层基石Spring IoC 容器、MyBatisORM、Servlet、动态代理全部基于反射实现。⚠️ 缺点性能较差反射绕开编译期优化大量反射调用会降低程序运行速度。破坏封装性通过setAccessible(true)可以强制访问private变量、方法违背面向对象封装原则。代码可读性差反射代码晦涩排错、维护难度高于普通正向代码。存在安全隐患可以绕过访问控制做非常规操作部分安全管理器会限制反射权限。六、典型应用场景Spring 框架IoC 容器通过反射实例化 Bean 对象依赖注入给属性赋值AOP 动态代理底层依赖反射调用目标方法。MyBatis解析 Mapper 接口反射创建接口代理对象自动封装数据库查询结果到实体类。通用工具类对象拷贝、JSON 序列化 / 反序列化FastJSON、Jackson 通过反射读写对象属性。配置文件加载读取 properties 配置中的类全限定名反射创建对应业务对象。单元测试框架 JUnit通过反射自动执行 Test 标记的测试方法。七、学习总结反射是 Java 从静态语言具备动态特性的核心基础虽然日常业务开发不会频繁手写反射代码但几乎所有主流开源框架底层都依赖反射。弄懂反射原理不仅能看懂框架底层源码逻辑也能理解注解、动态代理等进阶技术。使用反射时要权衡灵活性与性能、安全性高频调用场景尽量减少反射必要时可使用反射缓存、LambdaMetafactory 优化反射性能同时谨慎暴力访问私有成员避免破坏原有类设计。