核心定义

反射是 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);

注意事项

  1. 性能优化: 避免重复使用 class 对象、 method 等反射对象,因为对象是单例的,可以使用缓存存储。
  2. 类型安全: 反射调用应严格校验参数类型,否则会抛出 IllegalArgumentException(通常表示向方法传递了一个不合法或不适当的参数)。
  3. 访问控制: 访问私有成员时需调用 setAccessible(true),但可能受安全管理器(SecurityManager)限制(如某些安全沙箱环境)。
  4. 异常处理: 反射方法(如 invoke())会抛出 InvocationTargetException(目标方法本身的异常会被包装),需解包处理。