一、什么是反射1. 定义Java 反射Reflection程序在运行期间动态获取类的 Class 对象并且可以操作类里面的构造方法、成员变量、成员方法。正常编码是new 类名()→正向编码编译期确定类反射是运行时拿到 Class → 反向实例化对象、调用方法 →反向操作运行期确定类2. 核心Class 类JVM 加载 class 文件后会为每个类生成唯一的Class对象这个对象存储了类的所有信息属性、方法、构造器反射所有操作都依托Class对象。二、获取 Class 对象的 3 种方式java运行//1. 类名.class编译期 ClassUser clazz1 User.class; //2. 对象.getClass()已有实例对象 User user new User(); Class? extends User clazz2 user.getClass(); //3. Class.forName(全类名)最常用框架底层运行期加载 Class? clazz3 Class.forName(com.demo.User);框架Spring、MyBatis基本都是用第三种全类名配置实现解耦。三、反射四大常用操作实战代码先准备实体类 Userjava运行public class User { //私有成员变量 private String username; public Integer age; //无参构造 public User(){} //有参构造 public User(String username){ this.username username; } //私有方法 private void privateTest(){ System.out.println(私有方法执行); } //公共方法 public void show(String msg){ System.out.println(公共方法msg); } }1. 通过反射实例化对象java运行ClassUser clazz User.class; //1.无参构造创建对象 User u1 clazz.newInstance(); //2.获取有参构造器创建对象 ConstructorUser con clazz.getConstructor(String.class); User u2 con.newInstance(张三);2. 反射操作成员变量突破 private 私有权限java运行User user new User(); ClassUser clazz User.class; //获取私有字段username Field field clazz.getDeclaredField(username); field.setAccessible(true);//暴力破解取消权限检查 field.set(user,李四);//赋值 System.out.println(field.get(user));//取值李四3. 反射调用成员方法包括私有方法java运行User user new User(); ClassUser clazz User.class; //调用公共方法 Method show clazz.getMethod(show, String.class); show.invoke(user,hello反射); //调用私有方法 Method privateM clazz.getDeclaredMethod(privateTest); privateM.setAccessible(true); privateM.invoke(user);四、反射的实际开发应用场景Spring IoC 容器XML / 注解配置全类名反射创建 Bean 对象实现依赖注入MyBatis反射实例化 Mapper 接口、封装数据库查询结果到实体类通用工具类对象属性拷贝、序列化与反序列化配置文件解析读取 properties 里的类路径动态创建对象五、反射优缺点✅ 优点灵活性极高运行时动态创建对象、调用方法框架实现解耦的核心基石代码通用性强一套代码适配多个类工具类通用封装❌ 缺点性能偏低绕过编译优化比直接 new、直接调用方法慢破坏封装setAccessible(true)可以访问私有变量 / 私有方法违背面向对象封装特性安全隐患恶意代码通过反射篡改私有数据六、总结反射核心运行时依靠 Class 对象动态操作类结构打破编译期固定编码限制三大获取 Class 方式Class.forName()是框架标配能无视访问修饰符private暴力操作字段和方法是 Spring、MyBatis 等主流框架底层原理是 Java 高级必学知识点。
Java 反射机制详解:原理、使用、优缺点与实战案例
一、什么是反射1. 定义Java 反射Reflection程序在运行期间动态获取类的 Class 对象并且可以操作类里面的构造方法、成员变量、成员方法。正常编码是new 类名()→正向编码编译期确定类反射是运行时拿到 Class → 反向实例化对象、调用方法 →反向操作运行期确定类2. 核心Class 类JVM 加载 class 文件后会为每个类生成唯一的Class对象这个对象存储了类的所有信息属性、方法、构造器反射所有操作都依托Class对象。二、获取 Class 对象的 3 种方式java运行//1. 类名.class编译期 ClassUser clazz1 User.class; //2. 对象.getClass()已有实例对象 User user new User(); Class? extends User clazz2 user.getClass(); //3. Class.forName(全类名)最常用框架底层运行期加载 Class? clazz3 Class.forName(com.demo.User);框架Spring、MyBatis基本都是用第三种全类名配置实现解耦。三、反射四大常用操作实战代码先准备实体类 Userjava运行public class User { //私有成员变量 private String username; public Integer age; //无参构造 public User(){} //有参构造 public User(String username){ this.username username; } //私有方法 private void privateTest(){ System.out.println(私有方法执行); } //公共方法 public void show(String msg){ System.out.println(公共方法msg); } }1. 通过反射实例化对象java运行ClassUser clazz User.class; //1.无参构造创建对象 User u1 clazz.newInstance(); //2.获取有参构造器创建对象 ConstructorUser con clazz.getConstructor(String.class); User u2 con.newInstance(张三);2. 反射操作成员变量突破 private 私有权限java运行User user new User(); ClassUser clazz User.class; //获取私有字段username Field field clazz.getDeclaredField(username); field.setAccessible(true);//暴力破解取消权限检查 field.set(user,李四);//赋值 System.out.println(field.get(user));//取值李四3. 反射调用成员方法包括私有方法java运行User user new User(); ClassUser clazz User.class; //调用公共方法 Method show clazz.getMethod(show, String.class); show.invoke(user,hello反射); //调用私有方法 Method privateM clazz.getDeclaredMethod(privateTest); privateM.setAccessible(true); privateM.invoke(user);四、反射的实际开发应用场景Spring IoC 容器XML / 注解配置全类名反射创建 Bean 对象实现依赖注入MyBatis反射实例化 Mapper 接口、封装数据库查询结果到实体类通用工具类对象属性拷贝、序列化与反序列化配置文件解析读取 properties 里的类路径动态创建对象五、反射优缺点✅ 优点灵活性极高运行时动态创建对象、调用方法框架实现解耦的核心基石代码通用性强一套代码适配多个类工具类通用封装❌ 缺点性能偏低绕过编译优化比直接 new、直接调用方法慢破坏封装setAccessible(true)可以访问私有变量 / 私有方法违背面向对象封装特性安全隐患恶意代码通过反射篡改私有数据六、总结反射核心运行时依靠 Class 对象动态操作类结构打破编译期固定编码限制三大获取 Class 方式Class.forName()是框架标配能无视访问修饰符private暴力操作字段和方法是 Spring、MyBatis 等主流框架底层原理是 Java 高级必学知识点。