7 ответов:
Это должно продемонстрировать, как ее решить:
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)); } }выход:
5
лучший подход здесь-это использование Шаблон Visitor найдите все поля в классе и все суперклассы и выполните на них действие обратного вызова.
реализация
весна имеет хороший класс полезности
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 логическое пакета javax.управление.отношение.RoleUnresolvedList.typeSafe в классе типа javax.управление.отношение.RoleUnresolvedList
Найдено поле private transient boolean javax.управление.отношение.RoleUnresolvedList.испорчен в классе типа javax.управление.отношение.RoleUnresolvedList
Найдено поле private transient java.ленг.Объект [] java.утиль.список ArrayList.elementData в типе класса java.утиль.ArrayList
Найдено поле private int java.утиль.список ArrayList.размер в классе типа Ява.утиль.ArrayList
Найденное поле защищено переходным int java.утиль.AbstractList.modCount в классе типа java.утиль.AbstractList
это сделает это:
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; }
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); }
Мне нужно, чтобы добавить поддержку унаследованных полей для чертежей в Модель Гражданина. Я получил этот метод, который немного более лаконичен для получения полей класса + унаследованных полей.
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; }
Comments