核心定义
反射是
Java语言提供的一种可以运行时动态分析、操作类或对象的能力。允许程序在运行时获取类的完整元数据(包括类名、方法、字段、构造器等),并可以动态调用对象的方法、修改字段值、甚至可以直接方法私有成员。
核心机制
反射是在运行时 JVM 将每一个类创建一个唯一的 Class对象 (单例),用于存储该类的所有元数据(如类名、父类、接口、方法、字段、构造器等)。
获取 class 对象的三种方式:
//1. 通过类的静态属性 class(最常用)
Class<UserDemo> userDemoClass = UserDemo.class;
//2. 通过对象实例的 getClass() 方法
UserDemo userDemo = new UserDemo();
Class<? extends UserDemo> aClass = userDemo.getClass();
//3. 通过 Class.forName() 方法
Class<?> forName = Class.forName("learn.java.ancillary.UserDemo");反射的核心功能
操作构造器
动态创建类的实例(包括无参和有参方法)
@Data
public class UserDemo {
private String name;
private int age;
public UserDemo() {
}
public UserDemo(String name, int age) {
this.name = name;
this.age = age;
}
}
//通过无参构造器创建
UserDemo userDemo1 = UserDemo.class.newInstance();
//通过有参构造器创建
Constructor<UserDemo> constructor = UserDemo.class.getConstructor(String.class, int.class);
UserDemo userDemo2 = constructor.newInstance("zd", 18);操作字段
//获取public属性字段
UserDemo fieldUser = new UserDemo();
Field nameFiled = fieldUser.getClass().getField("sex");//获取sex字段
nameFiled.set(fieldUser, "zd");//设置sex字段的值
System.out.println(nameFiled.get(fieldUser));//获取sex字段的值
//获取private属性字段
Field sexField = fieldUser.getClass().getDeclaredField("sex");
sexField.setAccessible(true);//允许访问private字段
sexField.set(fieldUser, "男");
System.out.println(sexField.get(fieldUser));操作方法
//通过反射操作方法
UserDemo methodUser = new UserDemo("李四",12,"男");
//获取public方法
Method showPublicMethod = methodUser.getClass().getMethod("show");
showPublicMethod.invoke(methodUser);
//获取private方法
Method declaredMethod = methodUser.getClass().getDeclaredMethod("showP");
declaredMethod.setAccessible(true);//允许访问private方法
declaredMethod.invoke(methodUser);注意事项
- 性能优化: 避免重复使用
class对象、method等反射对象,因为对象是单例的,可以使用缓存存储。 - 类型安全: 反射调用应严格校验参数类型,否则会抛出
IllegalArgumentException(通常表示向方法传递了一个不合法或不适当的参数)。 - 访问控制: 访问私有成员时需调用
setAccessible(true),但可能受安全管理器(SecurityManager)限制(如某些安全沙箱环境)。 - 异常处理: 反射方法(如
invoke())会抛出InvocationTargetException(目标方法本身的异常会被包装),需解包处理。