我找到了一种通过来获取继承成员并通过来获得 class.getDeclaredFields();
私有成员的方法,class.getFields()
但是我正在寻找私有的继承字段。我怎样才能做到这一点?
我找到了一种通过来获取继承成员并通过来获得 class.getDeclaredFields();
私有成员的方法,class.getFields()
但是我正在寻找私有的继承字段。我怎样才能做到这一点?
Answers:
这应该演示如何解决它:
import java.lang.reflect.Field;
class Super {
private int i = 5;
}
public class B extends Super {
public static void main(String[] args) throws Exception {
B b = new B();
Field f = b.getClass().getSuperclass().getDeclaredField("i");
f.setAccessible(true);
System.out.println(f.get(b));
}
}
(或Class.getDeclaredFields
用于所有字段的数组。)
输出:
5
getSuperclass()
直到到达null
。
getDeclaredFields()[0]
,getDeclaredField("i")
而是[0]
在接下来的两个语句中重复数组访问?
getDeclaredFields
。答案已更新。
最好的方法是使用“ 访问者模式”在类和所有超类中查找所有字段,并对它们执行回调操作。
Spring有一个很好的Utility类ReflectionUtils
,它可以做到这一点:它定义了一种方法,用于通过回调在所有超类的所有字段上循环:ReflectionUtils.doWithFields()
在目标类的所有字段上调用给定的回调,在类层次结构中向上获取所有已声明的字段。
参数:
-clazz-要分析的目标类-fc-
每个字段要调用的回调
-ff-确定将回调应用到的字段的过滤器
ReflectionUtils.doWithFields(RoleUnresolvedList.class,
new FieldCallback(){
@Override
public void doWith(final Field field) throws IllegalArgumentException,
IllegalAccessException{
System.out.println("Found field " + field + " in type "
+ field.getDeclaringClass());
}
},
new FieldFilter(){
@Override
public boolean matches(final Field field){
final int modifiers = field.getModifiers();
// no static fields please
return !Modifier.isStatic(modifiers);
}
});
在类型类javax.management.relation.RoleUnresolvedList发现场私人短暂布尔javax.management.relation.RoleUnresolvedList.typeSafe
型类javax.management.relation.RoleUnresolvedList发现场私人短暂布尔javax.management.relation.RoleUnresolvedList.tainted
发现场类型类java.util.ArrayList中的私有瞬态java.lang.Object [] java.util.ArrayList.elementData
找到类型类java.util.ArrayList中的私有int java.util.ArrayList.size类型
发现了受保护的瞬态int java域。类型类java.util.AbstractList中的util.AbstractList.modCount
这样就可以了:
private List<Field> getInheritedPrivateFields(Class<?> type) {
List<Field> result = new ArrayList<Field>();
Class<?> i = type;
while (i != null && i != Object.class) {
Collections.addAll(result, i.getDeclaredFields());
i = i.getSuperclass();
}
return result;
}
如果使用EclEmma之类的代码覆盖工具,则必须当心:它们为每个类都添加了一个隐藏字段。在EclEmma的情况下,这些领域是明显的合成,而且可以过滤它们像这样:
private List<Field> getInheritedPrivateFields(Class<?> type) {
List<Field> result = new ArrayList<Field>();
Class<?> i = type;
while (i != null && i != Object.class) {
for (Field field : i.getDeclaredFields()) {
if (!field.isSynthetic()) {
result.add(field);
}
}
i = i.getSuperclass();
}
return result;
}
public static Field getField(Class<?> clazz, String fieldName) {
Class<?> tmpClass = clazz;
do {
try {
Field f = tmpClass.getDeclaredField(fieldName);
return f;
} catch (NoSuchFieldException e) {
tmpClass = tmpClass.getSuperclass();
}
} while (tmpClass != null);
throw new RuntimeException("Field '" + fieldName
+ "' not found on class " + clazz);
}
(基于此答案)
实际上,我使用的是复杂类型的层次结构,因此您的解决方案并不完整。我需要进行递归调用以获取所有私有继承字段。这是我的解决方案
/**
* Return the set of fields declared at all level of class hierachy
*/
public Vector<Field> getAllFields(Class clazz) {
return getAllFieldsRec(clazz, new Vector<Field>());
}
private Vector<Field> getAllFieldsRec(Class clazz, Vector<Field> vector) {
Class superClazz = clazz.getSuperclass();
if(superClazz != null){
getAllFieldsRec(superClazz, vector);
}
vector.addAll(toVector(clazz.getDeclaredFields()));
return vector;
}
我需要在Model Citizen中添加对蓝图的继承字段的支持。我派生了此方法,该方法对于检索类的字段+继承的字段更加简洁。
private List<Field> getAllFields(Class clazz) {
List<Field> fields = new ArrayList<Field>();
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
Class superClazz = clazz.getSuperclass();
if(superClazz != null){
fields.addAll(getAllFields(superClazz));
}
return fields;
}
private static Field getField(Class<?> clazz, String fieldName) {
Class<?> tmpClass = clazz;
do {
for ( Field field : tmpClass.getDeclaredFields() ) {
String candidateName = field.getName();
if ( ! candidateName.equals(fieldName) ) {
continue;
}
field.setAccessible(true);
return field;
}
tmpClass = tmpClass.getSuperclass();
} while ( clazz != null );
throw new RuntimeException("Field '" + fieldName +
"' not found on class " + clazz);
}