是否可以在不使用field.setAccessible(true);
的情况下获取字段值?
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
Object value = field.get(object);
我的意思是,我可以简单地授予对特定类的所有私有字段的访问权限,而不必在每次读取时调用setter吗?
答案 0 :(得分:4)
您不必为每个字段访问重复该操作。每个类/字段只需执行一次,但有一种有效的方法:
static final class Accessor extends ClassValue<Map<String,Field>> {
@Override protected Map<String, Field> computeValue(Class<?> type) {
Field[] fields=type.getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
Map<String,Field> map=new HashMap<>(fields.length);
for(Field f: fields) map.put(f.getName(), f);
return map;
}
}
static final Accessor FIELD_ACCESSOR = new Accessor();
使您的访问变得像
一样简单Object value = FIELD_ACCESSOR.get(o.getClass()).get(fieldName).get(o);
请注意,ClassValue
负责每个类只执行一次操作,而缓存的值不会阻止类垃圾收集,AccessibleObject.setAccessible(…)
将一次应用于所有声明的字段。
但请记住,这些只是实际类的声明字段,您必须手动迭代超类层次结构以搜索其字段。字段名称不必在类层次结构中是唯一的。
答案 1 :(得分:1)
不,你不能。什么是为了什么?您可以准备一次Field对象,对其进行缓存并将其用于多次读取。
// do it once
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
// use many times:
for(million times)
Object value = field.get(object);