Java 反射机制详解:从原理到实战

Java 反射机制详解:从原理到实战 一、什么是 Java 反射机制反射Reflection是 Java 语言提供的一种基础功能它允许程序在 ** 运行时Runtime** 动态地获取任意类的完整信息并能对类或对象进行操作比如创建实例、调用方法、访问 / 修改字段值甚至突破 private 权限限制。简单来说编译期你不知道的类反射能让你在运行时 “看透它、操控它”这也是 Spring、MyBatis 等主流框架实现 “约定大于配置” 的核心基础。二、反射的核心原理Class 对象Java 中所有类在被 JVM 加载后都会自动生成一个对应的java.lang.Class对象这个对象包含了该类的所有元信息类名、父类、接口、字段、方法、构造器等。反射的本质就是通过操作这个Class对象实现对类的动态访问和控制。获取Class对象的三种方式// 方式1通过类名的class属性编译期已知类ClassUser clazz1 User.class;// 方式2通过对象的getClass()方法已有对象实例User user new User();Class? extends User clazz2 user.getClass();// 方式3通过全限定类名的静态方法运行时动态获取最常用Class? clazz3 Class.forName(com.example.entity.User);三、反射常用操作实战下面用一个简单的User类演示反射的核心操作// 目标实体类public class User {private String name;public int age;public User() {}public User(String name, int age) {this.name name;this.age age;}private void sayHello(String message) {System.out.println(Hello, message);}public void printInfo() {System.out.println(Name: name , Age: age);}}1. 动态创建对象实例public class ReflectDemo {public static void main(String[] args) throws Exception {// 1. 获取Class对象Class? clazz Class.forName(com.example.entity.User);// 方式1调用无参构造器创建对象Object obj1 clazz.newInstance(); // JDK9已过时推荐用构造器方式// 方式2调用有参构造器创建对象推荐Constructor? constructor clazz.getConstructor(String.class, int.class);Object obj2 constructor.newInstance(张三, 20);}}2. 动态调用方法// 获取对象Object userObj clazz.getConstructor().newInstance();// 调用public方法Method printInfoMethod clazz.getMethod(printInfo);printInfoMethod.invoke(userObj); // 输出Name: null, Age: 0// 调用private方法需突破权限Method sayHelloMethod clazz.getDeclaredMethod(sayHello, String.class);sayHelloMethod.setAccessible(true); // 关键关闭权限检查sayHelloMethod.invoke(userObj, 反射你好); // 输出Hello, 反射你好3. 动态访问 / 修改字段Object userObj clazz.getConstructor(String.class, int.class).newInstance(李四, 22);// 访问public字段Field ageField clazz.getField(age);System.out.println(age的值 ageField.get(userObj)); // 输出22// 访问private字段需突破权限Field nameField clazz.getDeclaredField(name);nameField.setAccessible(true);System.out.println(name的值 nameField.get(userObj)); // 输出李四// 修改字段值nameField.set(userObj, 王五);ageField.set(userObj, 25);((User)userObj).printInfo(); // 输出Name: 王五, Age: 25四、反射的核心特点与应用场景✅ 优点灵活性极强突破编译期限制实现动态加载和操作类是框架开发的基石Spring 的 IOC 容器、MyBatis 的 ORM 映射、动态代理都依赖反射实现可用于实现通用工具类比如之前讲的通用方法计时工具⚠️ 缺点存在性能与安全问题性能较低反射绕过了编译期优化且权限检查会增加额外开销比直接调用慢很多破坏封装可以访问和修改 private 成员可能导致安全隐患可读性差反射代码逻辑复杂调试难度高不利于维护常见应用场景框架开发Spring 的 Bean 创建、依赖注入MyBatis 的数据库 ORM 映射通用工具类JSON 序列化 / 反序列化、对象拷贝工具动态代理AOP 切面编程、日志记录、事务控制插件化开发运行时加载第三方插件实现功能扩展五、反射的常见面试考点反射的基本原理JVM 加载类生成 Class 对象通过 Class 对象操作类的元信息获取 Class 对象的三种方式类名.class、对象.getClass()、Class.forName()getMethod()和getDeclaredMethod()的区别getMethod()只能获取 public 方法包括父类的 public 方法getDeclaredMethod()可以获取本类中所有声明的方法包括 private但不包括父类方法setAccessible(true)的作用关闭 Java 语言访问检查突破 private/protected 权限限制反射的性能问题为什么反射比直接调用慢如何优化六、总结反射是 Java 实现动态性的核心特性它让程序在运行时拥有了 “自省和自操控” 的能力是理解主流框架底层原理的关键。但它的性能开销和安全隐患也不容忽视日常开发中应避免滥用仅在需要动态性的场景下使用。