获取类的Class对象3种方法:

  1. Class clazz = Class.forName("Animal");
  2. Class clazz = User.class;
  3. User user = new User(); Class clazz = user.getClass();

1 获取并使用构造方法

  • getConstructor(Class<?>... paramTypes):获取单个 public 构造(参数类型匹配)
  • getDeclaredConstructor(Class<?>... paramTypes):获取单个任意权限构造(含 private)
  • getConstructors():获取所有 public 构造(返回Constructor[]数组)
  • getDeclaredConstructors():获取所有构造(含 private,返回Constructor[]数组)
// 01:公共方法无参构造
public User() {
    
}
// 公共方法有参构造
public User(String name) {
    this.name = name;
}
// 02:私有方法有参构造
private User(String name, int age) {
    this.name = name;
    this.age = age;
}
// 先获取类Class对象
Class<User> userClazz = User.class;
// 根据参数类型匹配,获取公共方法无参构造对象,参数null可省略
Constructor<User> constructor = userClazz.getConstructor();
// 利用构造器创建对象
User user1 = constructor.newInstance();

// 获取私有方法有参构造,根据参数类型来匹配。
Constructor<User> privateConstructor = userClazz.getDeclaredConstructor(String.class, int.class);

// 绕过权限检查(关键!否则抛IllegalAccessException)
privateConstructor.setAccessible(true);

// 调用构造器创建对象(传入实际参数)
User user2 = privateConstructor.newInstance("张三", 20);

// 获取所有公共构造
Constructor[] constructors = userClazz.getConstructors();
// 获取所有任意权限构造
Constructor[] allDeclaredConstructors = studentClass.getDeclaredConstructors();

2 get/set成员变量

  • getField(String name):获取单个 public 成员变量(含父类继承的)
  • getDeclaredField(String name):获取单个本类任意权限成员变量(不含父类)
  • getFields():获取所有 public 成员变量(返回Field[]
  • getDeclaredFields():获取所有本类成员变量(含 private,返回Field[]
  • Type 实例对象变量值 = (Type) Class变量字段.get(实例对象)
  • Class变量字段.set(实例对象, 新值)
// 利用之前获取的构造器,创建对象
User user2 = privateConstucotr.newInstance("张三",20);
// 获取Class对象的变量
Field nameField = userClazz.getField("name");
String oldName = (String) nameField.get(user2);
nameField.set(user2, "李四");
// 操作私有变量,需要绕过权限
Field ageField = userClazz.getDeclaredField("age");
ageField.setAccessible(true); // 关闭访问检查
int oldAge = (int) ageField.get(user2);
ageField.set(user2, 25);
int newAge = (int) ageField.get(user2);

3 get并调用成员方法

  • getMethod(String name, Class<?>... paramTypes):获取单个 public 方法(含父类继承的)
  • getDeclaredMethod(String name, Class<?>... paramTypes):获取单个本类任意权限方法(含 private)
  • getMethods():获取所有 public 方法(含Object类继承的,返回Method[]
  • getDeclaredMethods():获取所有本类方法(含 private,返回Method[]

注意获取Method时要带参数来匹配。

静态方法属于类,不属于实例对象,因此invoke()的第一个参数应该传null。

// 1. public无参方法
public void showInfo() {
    System.out.println("姓名:" + name + ",年龄:" + age);
}

// 2. private有参方法(参数为String)
private String sayHello(String target) {
    return "Hello, " + target;
}

// 3. public静态方法(参数为int,返回int)
public static int add(int a, int b) {
    return a + b;
}
Method showInfoMethod = userClazz.getMethod("showInfo");
// 执行实例对象的方法:invoke(对象实例, 参数);(无参null可省略)
showInfoMethod.invoke(user2);

// 私有方法,绕过检查
Method sayHelloMethod = userClazz.getDeclaredMethod("sayHello");
sayHelloMethod.setAccessible(true);
String result = (String) sayHelloMethod.invoke(user2, "Hello");
System.out.println(result);
Method addMethod = userClazz.getMethod("add", int.class, int.class);
int sum = (int) addMethod.invoke(null, 10, 20);
System.out.println(sum);

利用反射,实现通用对象数据保存

public static void saveObject(Object obj) throws Exception {
    // 1. 获取Class对象
    Class<?> clazz = obj.getClass();
    System.out.println("=====" + clazz.getSimpleName() + "对象数据=====");

    // 2. 获取所有成员变量(含private)
    Field[] fields = clazz.getDeclaredFields();

    // 3. 遍历变量并输出
    for (Field field : fields) {
        // 绕过权限检查
        field.setAccessible(true);
        // 获取变量名
        String fieldName = field.getName();
        // 获取变量值(需传入对象实例)
        Object fieldValue = field.get(obj);
        // 格式化输出
        System.out.println(fieldName + " = " + fieldValue);
    }
}

// 测试:传入User对象和Book对象(自定义Book类含name、price)
public static void main(String[] args) throws Exception {
    User user = new User("王五", 30);
    Book book = new Book("Java反射", 59.9);
    
    saveObject(user); // 输出User的name和age
    saveObject(book); // 输出Book的name和price
}
分类: Java-Backend 标签: Java

评论

暂无评论数据

暂无评论数据

目录