Java通过反射修改成员变量的值
- 关于反射中的Field类的详细介绍请看这里
本篇重点在于记录一些使用上的一些小问题
下面的例子是通过反射在运行时改变TestMapReflect类中的map属性值。
//TestMapReflect.java
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class TestMapReflect {
public Map<String, Integer> map = new HashMap<>();
public static void main(String[] args) {
TestMapReflect testMapReflect = new TestMapReflect();
testMapReflect.map.put("Main", 1);
try {
//获取Class对象
Class clz = Class.forName("TestMapReflect");
//获取map属性
Field mapFiled = clz.getDeclaredField("map");
//设置可修改
mapFiled.setAccessible(true);
//创建新的map
Map<String,Integer> newMap = new HashMap<>();
newMap.put("ReflectMain", 2);
//set方法设置map属性为新创建的newMap
mapFiled.set(testMapReflect,newMap);
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("in TestMapReflect "+ testMapReflect.map);
}
}
整个过程中规中矩,就是新创建一个Map对象,通过set方法(Map为引用数据类型)将原属性值替换掉。
运行结果:
-
问题:是否可以创建匿名对象来替换掉原属性值?
下面来验证:
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class TestMapReflect {
public Map<String, Integer> map = new HashMap<>();
public static void main(String[] args) {
TestMapReflect testMapReflect = new TestMapReflect();
testMapReflect.map.put("Main", 1);
try {
//获取Class对象
Class clz = Class.forName("TestMapReflect");
//获取map属性
Field mapFiled = clz.getDeclaredField("map");
//设置可修改
mapFiled.setAccessible(true);
//创建新的map
// Map<String,Integer> newMap = new HashMap<>();
// newMap.put("ReflectMain", 2);
//set方法设置map属性为新创建的newMap
// mapFiled.set(testMapReflect,newMap);
mapFiled.set(testMapReflect,new HashMap<String, Integer>().put("ReflectMain", 2));
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("in TestMapReflect "+ testMapReflect.map);
}
}
运行结果:
说明:考虑是匿名对象调用了put方法后,再无对象引用它,所以垃圾回收机制将它回收了,所以set方法拿到的值为null。