通过反射修改对象私有变量
面向对象的特征之一就是封装性,如果一个对象的成员变量被设置为私有的,那么从正常编程的角度出发,是无法进行修改的。但是有了反射机制,就可以破坏面向对象的封装性,去修改私有变量的值。
首先,定义个Person类,成员变量定义为私有的
public class Person { private String name; private int age; public Person(String name, int age){ this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
然后,编写客户端代码,首先创建Person对象,通过构造函数的方式初始化成员变量的值。由于没有公共的方法可以修改成员变量的值,该对象其实就是一个只读的对象了。
先输出一下Person对象,再通过反射的方式修改Person对象的name字段,再次输出进行对比。
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { Person person = new Person("徐雅静", 18); System.out.println(person.toString()); rename(person); System.out.println(person.toString()); } private static void rename(Person person) throws NoSuchFieldException, IllegalAccessException { Class<? extends Person> clazz = person.getClass(); Field field = clazz.getDeclaredField("name"); // 这一步不能少,否则会报如下异常 // Class com.foo.PersonMain can not access a member of class com.foo.Person with modifiers "private" field.setAccessible(true); field.set(person, "黄俊杰"); }
输出结果如下,从输出结果中可以看到Person对象的name字段的值,由 “徐雅静”,改为了 “黄俊杰”。
Person [name=徐雅静, age=18] Person [name=黄俊杰, age=18]