una - reflexion java example
Recuperando los nombres/valores heredados de los atributos usando Java Reflection (10)
Tengo un objeto Java ''ChildObj'' que se extiende desde ''ParentObj''. Ahora, si es posible recuperar todos los nombres de atributos y valores de ChildObj, incluidos los atributos heredados también, utilizando el mecanismo de reflexión de Java?
Class.getFields me da la matriz de atributos públicos, y Class.getDeclaredFields me da la matriz de todos los campos, pero ninguno de ellos incluye la lista de campos heredados.
¿Hay alguna manera de recuperar los atributos heredados también?
Las soluciones recursivas están bien, el único problema pequeño es que devuelven un superconjunto de miembros declarados y heredados. Tenga en cuenta que el método getDeclaredFields () devuelve también métodos privados. Por lo tanto, dado que navega por toda la jerarquía de superclase, incluirá todos los campos privados declarados en las superclases, y no se heredarán.
Un filtro simple con un Modifier.isPublic || El predicado Modifier.isProtected haría:
import static java.lang.reflect.Modifier.isPublic;
import static java.lang.reflect.Modifier.isProtected;
(...)
List<Field> inheritableFields = new ArrayList<Field>();
for (Field field : type.getDeclaredFields()) {
if (isProtected(field.getModifiers()) || isPublic(field.getModifiers())) {
inheritableFields.add(field);
}
}
Más corto y con menos objetos instanciados? ^^
private static Field[] getAllFields(Class<?> type) {
if (type.getSuperclass() != null) {
return (Field[]) ArrayUtils.addAll(getAllFields(type.getSuperclass()), type.getDeclaredFields());
}
return type.getDeclaredFields();
}
Necesita llamar:
Class.getSuperclass().getDeclaredFields()
Recurriendo a la jerarquía de herencia según sea necesario.
Puedes probar:
Class parentClass = getClass().getSuperclass();
if (parentClass != null) {
parentClass.getDeclaredFields();
}
Si, en cambio, deseabas confiar en una biblioteca para lograr esto, Apache Commons Lang versión 3.2+ proporciona 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<Field> allFields = FieldUtils.getAllFieldsList(LinkedList.class);
// Get the fields form each individual class in the type''s hierarchy
final List<Field> allFieldsClass = Arrays.asList(LinkedList.class.getFields());
final List<Field> allFieldsParent = Arrays.asList(AbstractSequentialList.class.getFields());
final List<Field> allFieldsParentsParent = Arrays.asList(AbstractList.class.getFields());
final List<Field> 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));
}
}
Use la biblioteca Reflections:
public Set<Field> getAllFields(Class<?> aClass) {
return org.reflections.ReflectionUtils.getAllFields(aClass);
}
no, debes escribirlo tú mismo. Es un método recursivo simple llamado en Class.getSuperClass() :
public static List<Field> getAllFields(List<Field> 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<Field>(), LinkedList.class));
}
public static List<Field> getAllFields(Class<?> type) {
List<Field> fields = new ArrayList<Field>();
for (Class<?> c = type; c != null; c = c.getSuperclass()) {
fields.addAll(Arrays.asList(c.getDeclaredFields()));
}
return fields;
}
private static void addDeclaredAndInheritedFields(Class c, Collection<Field> fields) {
fields.addAll(Arrays.asList(c.getDeclaredFields()));
Class superClass = c.getSuperclass();
if (superClass != null) {
addDeclaredAndInheritedFields(superClass, fields);
}
}
private static void addDeclaredAndInheritedFields(Class<?> c, Collection<Field> fields) {
fields.addAll(Arrays.asList(c.getDeclaredFields()));
Class<?> superClass = c.getSuperclass();
if (superClass != null) {
addDeclaredAndInheritedFields(superClass, fields);
}
}
Versión de trabajo de la solución "DidYouMeanThatTomHa ..." anterior