Я нашел способ получить унаследованные члены через class.getDeclaredFields ();
и доступ к закрытым членам через class.getFields ()
Но я ищу частные унаследованные поля.
Как мне этого добиться?
На самом деле я использую сложную иерархию типов, поэтому ваше решение не завершено. Мне нужно сделать рекурсивный вызов, чтобы получить все частные унаследованные поля. Вот мое решение
/**
* 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;
}
Лучшим подходом здесь является использование шаблона посетителей . действительно находит все поля в классе и все суперклассы и выполняет для них обратный вызов.
Spring имеет хороший служебный класс 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);
}
});
Найдено поле private transient boolean javax.management.relation.RoleUnresolvedList.typeSafe в классе типа javax.management.relation .RoleUnresolvedList
Найдено поле private transient boolean javax.management.relation.RoleUnresolvedList.tainted в классе типов javax.management.relation.RoleUnresolvedList
Найдено поле private transient java.lang.Object [] java.util.ArrayList.elementData в классе типов java.util.ArrayList
Найдено поле private int java.util.ArrayList.size в классе типов java.util.ArrayList
Найдено поле с защищенным переходным процессом int java.util.AbstractList.modCount в классе типов java.util.AbstractList
Это должно продемонстрировать, как ее решить:
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[] fs = b.getClass().getSuperclass().getDeclaredFields();
fs[0].setAccessible(true);
System.out.println(fs[0].get(b));
}
}
Output:
5
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);
}