Récupération des noms / valeurs d’atsortingbuts hérités à l’aide de Java Reflection

J’ai un object Java ‘ChildObj’ qui est étendu de ‘ParentObj’. Maintenant, s’il est possible de récupérer tous les noms d’atsortingbuts et les valeurs de ChildObj, y compris les atsortingbuts hérités, en utilisant le mécanisme de reflection Java?

Class.getFields me donne le tableau des atsortingbuts publics et Class.getDeclaredFields me donne le tableau de tous les champs, mais aucun d’entre eux n’inclut la liste des champs hérités.

Existe-t-il un moyen de récupérer les atsortingbuts hérités également?

non, vous devez l’écrire vous-même. C’est une méthode récursive simple appelée Class.getSuperClass () :

public static List getAllFields(List fields, Class type) { fields.addAll(Arrays.asList(type.getDeclaredFields())); if (type.getSuperclass() != null) { getAllFields(fields, type.getSuperclass()); } return fields; } @Test public void getLinkedListFields() { System.out.println(getAllFields(new LinkedList(), LinkedList.class)); } 
  public static List getAllFields(Class type) { List fields = new ArrayList(); for (Class c = type; c != null; c = c.getSuperclass()) { fields.addAll(Arrays.asList(c.getDeclaredFields())); } return fields; } 

Si, au lieu de cela, vous vouliez vous fier à une bibliothèque pour y parvenir, Apache Commons Lang version 3.2+ fournit FieldUtils.getAllFieldsList :

 import java.lang.reflect.Field; import java.util.AbstractCollection; import java.util.AbstractList; import java.util.AbstractSequentialList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import org.apache.commons.lang3.reflect.FieldUtils; import org.junit.Assert; import org.junit.Test; public class FieldUtilsTest { @Test public void testGetAllFieldsList() { // Get all fields in this class and all of its parents final List allFields = FieldUtils.getAllFieldsList(LinkedList.class); // Get the fields form each individual class in the type's hierarchy final List allFieldsClass = Arrays.asList(LinkedList.class.getFields()); final List allFieldsParent = Arrays.asList(AbstractSequentialList.class.getFields()); final List allFieldsParentsParent = Arrays.asList(AbstractList.class.getFields()); final List allFieldsParentsParentsParent = Arrays.asList(AbstractCollection.class.getFields()); // Test that `getAllFieldsList` did truly get all of the fields of the the class and all its parents Assert.assertTrue(allFields.containsAll(allFieldsClass)); Assert.assertTrue(allFields.containsAll(allFieldsParent)); Assert.assertTrue(allFields.containsAll(allFieldsParentsParent)); Assert.assertTrue(allFields.containsAll(allFieldsParentsParentsParent)); } } 

Vous devez appeler:

 Class.getSuperclass().getDeclaredFields() 

Si nécessaire, récurer la hiérarchie d’inheritance.

Utiliser la bibliothèque de reflections:

 public Set getAllFields(Class aClass) { return org.reflections.ReflectionUtils.getAllFields(aClass); } 

Les solutions récursives sont correctes, le seul problème est qu’elles renvoient un sur-ensemble de membres déclarés et hérités. Notez que la méthode getDeclaredFields () renvoie également les méthodes privées. Donc, étant donné que vous naviguez dans toute la hiérarchie de la superclasse, vous allez inclure tous les champs privés déclarés dans les superclasses, et ceux-ci ne sont pas hérités.

Un simple filtre avec un Modifier.isPublic || Modifier.is Le prédicat protégé ferait:

 import static java.lang.reflect.Modifier.isPublic; import static java.lang.reflect.Modifier.isProtected; (...) List inheritableFields = new ArrayList(); for (Field field : type.getDeclaredFields()) { if (isProtected(field.getModifiers()) || isPublic(field.getModifiers())) { inheritableFields.add(field); } } 
 private static void addDeclaredAndInheritedFields(Class c, Collection fields) { fields.addAll(Arrays.asList(c.getDeclaredFields())); Class superClass = c.getSuperclass(); if (superClass != null) { addDeclaredAndInheritedFields(superClass, fields); } } 

Version de travail de la solution “DidYouMeanThatTomHa …” ci-dessus

Tu peux essayer:

  Class parentClass = getClass().getSuperclass(); if (parentClass != null) { parentClass.getDeclaredFields(); } 

Plus court et avec moins d’instanciation d’object? ^^

 private static Field[] getAllFields(Class type) { if (type.getSuperclass() != null) { return (Field[]) ArrayUtils.addAll(getAllFields(type.getSuperclass()), type.getDeclaredFields()); } return type.getDeclaredFields(); } 
 private static void addDeclaredAndInheritedFields(Class c, Collection fields) { fields.addAll(Arrays.asList(c.getDeclaredFields())); Class superClass = c.getSuperclass(); if (superClass != null) { addDeclaredAndInheritedFields(superClass, fields); } }