可以通過類對象的 getDeclaredField()方法字段(Field)對象,然后再通過字段
對象的 setAccessible(true)將其設置為可以訪問,接下來就可以通過 get/set 方
法來獲取/設置字段的值了。下面的代碼實現了一個反射的工具類,其中的兩個靜
態方法分別用於獲取和設置私有字段的值,字段可以是基本類型也可以是對象類
型且支持多級對象操作,例如 ReflectionUtil.get(dog, “owner.car.engine.id”);
可以獲得 dog 對象的主人的汽車的引擎的 ID 號。
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;import java.util.List;
/**
* 反射工具類
* @author 駱昊
*
*/
public class ReflectionUtil {
private ReflectionUtil() {
throw new AssertionError();
}
/**
* 通過反射取對象指定字段(屬性)的值
* @param target 目標對象
* @param fieldName 字段的名字
* @throws 如果取不到對象指定字段的值則拋出異常
* @return 字段的值
*/
public static Object getValue(Object target, String fieldName) {
Class<?> clazz = target.getClass();
String[] fs = fieldName.split("\\.");
try {
for(int i = 0; i < fs.length - 1; i++) {
Field f = clazz.getDeclaredField(fs[i]);
f.setAccessible(true);
target = f.get(target);
clazz = target.getClass();
}
Field f = clazz.getDeclaredField(fs[fs.length - 1]);
f.setAccessible(true);
return f.get(target);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 通過反射給對象的指定字段賦值
* @param target 目標對象
* @param fieldName 字段的名稱
* @param value 值
*/
public static void setValue(Object target, String fieldName, Object
value) {
Class<?> clazz = target.getClass();
String[] fs = fieldName.split("\\.");
try {
for(int i = 0; i < fs.length - 1; i++) {
Field f = clazz.getDeclaredField(fs[i]);
f.setAccessible(true);
Object val = f.get(target);
if(val == null) {
Constructor<?> c =
f.getType().getDeclaredConstructor();
c.setAccessible(true);
val = c.newInstance();
f.set(target, val);
}
target = val;
clazz = target.getClass();
}
Field f = clazz.getDeclaredField(fs[fs.length - 1]);
f.setAccessible(true);
f.set(target, value);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}