杰瑞科技汇

java 反射 获取私有属性值

Java 反射获取私有属性值

在 Java 中,可以通过反射机制来获取和修改私有属性值,以下是详细的方法和示例代码:

基本步骤

  1. 获取类的 Class 对象
  2. 获取 Field 对象(指定属性名)
  3. 设置可访问性(忽略访问修饰符检查)
  4. 获取或设置属性值

示例代码

定义一个测试类

public class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

使用反射获取私有属性值

import java.lang.reflect.Field;
public class ReflectionExample {
    public static void main(String[] args) throws Exception {
        // 创建对象实例
        Person person = new Person("张三", 25);
        // 获取 Class 对象
        Class<?> clazz = person.getClass();
        // 获取私有字段 name
        Field nameField = clazz.getDeclaredField("name");
        // 设置可访问性(关键步骤)
        nameField.setAccessible(true);
        // 获取字段值
        String nameValue = (String) nameField.get(person);
        System.out.println("姓名: " + nameValue);
        // 获取私有字段 age
        Field ageField = clazz.getDeclaredField("age");
        ageField.setAccessible(true);
        // 获取字段值
        int ageValue = ageField.getInt(person);
        System.out.println("年龄: " + ageValue);
    }
}

关键点说明

  1. getDeclaredField(String name):获取类中声明的指定字段(包括私有字段)

    • getField() 不同,后者只能获取 public 字段
  2. setAccessible(true):设置可访问性,这是获取私有字段值的关键步骤

    这会关闭 Java 语言的访问检查,允许访问私有成员

  3. get(Object obj):获取指定对象的字段值

    • 对于基本类型,有对应的方法如 getInt(), getBoolean()

获取静态私有字段

如果要获取静态私有字段,不需要传入对象实例:

Field staticField = clazz.getDeclaredField("STATIC_FIELD");
staticField.setAccessible(true);
Object value = staticField.get(null); // 静态字段传入 null

注意事项

  1. 反射会破坏封装性,应谨慎使用
  2. 安全管理器可能会阻止反射访问私有成员
  3. 反射操作比直接访问慢,性能敏感场景应避免使用
  4. 在模块化系统(Java 9+)中,可能需要额外的模块声明才能访问非导出包中的类

完整示例(包含修改私有字段)

import java.lang.reflect.Field;
public class ReflectionFullExample {
    public static void main(String[] args) throws Exception {
        Person person = new Person("李四", 30);
        // 获取并修改私有字段
        Field nameField = person.getClass().getDeclaredField("name");
        nameField.setAccessible(true);
        // 获取当前值
        String currentName = (String) nameField.get(person);
        System.out.println("修改前: " + currentName);
        // 修改值
        nameField.set(person, "王五");
        // 获取修改后的值
        String newName = (String) nameField.get(person);
        System.out.println("修改后: " + newName);
    }
}

通过反射,Java 程序可以在运行时动态地检查和修改类的私有成员,但应遵循"最小权限原则",仅在必要时使用。

分享:
扫描分享到社交APP
上一篇
下一篇