通过反射获取第一个父级的字段

Getting first parent's fields via reflection

提问人:Luchian Grigore 提问时间:11/1/2011 更新时间:4/13/2018 访问量:27989

问:

我正在尝试获取对象的第一个父级的字段和值。我目前的代码是这样的:

Class<? extends Object> cls = obj.getClass();
Field[] fields = cls.getDeclaredFields();
for ( Field field : fields )
{
    String fieldName = field.getName();
    String fieldValue = field.get(obj);
}

我的类结构类似于:

class A
{
    int x;
}

class B extends A
{
    int y;
}

class C extends B
{
    int z;
}

现在,我将一个 C 对象传递给该方法,我想从 C 和 B 获取所有字段,而不是从 A 获取所有字段。有没有办法做到这一点(使用反射,我不想实现其他方法)?

Java 反射

评论


答:

11赞 Peter Lawrey 11/1/2011 #1

创建方法

public static void printFieldsFor(Class cls, Object obj) {
  Field[] fields = cls.getDeclaredFields();
  for ( Field field : fields ) {
    String fieldName = field.getName();
    String fieldValue = field.get(obj);
  }
}

printFieldsFor(object.getClass(), obj);
printFieldsFor(object.getClass().getSuperclass(), obj);

或使用循环

for(Class cls = object.getClass(); 
    cls!=null && cls!=A.class; 
    cls = cls.getSuperclass()) {
  for(Field field : cls.getDeclaredFields()) {
     String fieldName = field.getName();
     String fieldValue = field.get(obj);
     // do something with the field.
  }
}
28赞 DejanLekic 11/1/2011 #2

Luchian,请使用 getSuperclass() 方法获取对 Class 对象的引用,该对象表示相关对象的超类类型。之后,您将很容易像在示例中一样获取字段。

-4赞 Muhammad Suleman 4/24/2014 #3

您可以使用此代码从任何类中获取字段,而不管其父类或子类如何

for (Field field : YourClassName.class.getDeclaredFields()) {
  //fields
}

评论

2赞 Arnaud 6/19/2015
错误:来自 javadoc :返回一个 Field 对象数组,该数组反映了此 Class 对象所表示的类或接口声明的所有字段。这包括公共字段、受保护字段、默认(包)访问字段和私有字段,但不包括继承的字段
0赞 Pablo de Castro Barbosa 4/13/2018 #4
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author pablo.barbosa (2017-08-15)
 */
public class ReflectionUtil {

    /**
     * Hiding constructor. The methods are statics
     */
    private ReflectionUtil() {
        // Hiding constructor
    }

    public static List<Field> getInheritedDeclaredFields(Class<?> fromClass, Class<?> stopWhenClass) {
        if (stopWhenClass == null) {
            stopWhenClass = Object.class;
        }
        List<Field> fields = new ArrayList<>();
        List<Class<?>> classes = new ArrayList<>();

        Class<?> cls = fromClass;
        do {
            classes.add(cls);
            cls = cls.getSuperclass();
        } while (cls != null && !cls.equals(stopWhenClass));

        for (int i = classes.size() - 1; i >= 0; i--) {
            fields.addAll(Arrays.asList(classes.get(i).getDeclaredFields()));
        }

        return fields;
    }

    public static Field getInheritedDeclaredField(Class<?> fromClass, String fieldName, Class<?> stopWhenClass) throws NoSuchFieldException {
        if (stopWhenClass == null) {
            stopWhenClass = Object.class;
        }

        Class<?> cls = fromClass;
        do {
            Field field;
            try {
                field = cls.getDeclaredField(fieldName);
                if (field != null) {
                    return field;
                }
            } catch (NoSuchFieldException | SecurityException e) {
                // Nothing. We'll try to get field from superclass
            }
            cls = cls.getSuperclass();
        } while (cls != null && !cls.equals(stopWhenClass));

        // If we got here, we'll throw an exception
        throw new NoSuchFieldException(fieldName);
    }

    public static Object getInheritedDeclaredFieldValue(Object obj, String fieldName, Class<?> stopWhenClass) throws NoSuchFieldException, IllegalAccessException {
        Field field = getInheritedDeclaredField(obj.getClass(), fieldName, stopWhenClass);
        field.setAccessible(true);
        return field.get(obj);
    }

}

评论

6赞 André 4/13/2018
通常最好不要只发布带有答案的代码。但也要解释为什么。