【问题标题】:Getting first parent's fields via reflection通过反射获取第一父母的字段
【发布时间】:2018-04-13 21:00:00
【问题描述】:

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

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 reflection


    【解决方案1】:

    Luchian,使用getSuperclass() 方法获取对表示所讨论对象的超类类型的Class 对象的引用。之后,您将可以轻松地以与示例中相同的方式获取字段。

    【讨论】:

      【解决方案2】:

      创建一个方法

      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.
        }
      }
      

      【讨论】:

        【解决方案3】:
        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);
            }
        
        }
        

        【讨论】:

        • 通常最好不要只发布带有答案的代码。但也要解释原因。
        【解决方案4】:

        您可以使用此代码简单地从任何类中获取字段,无论其父类还是子类

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

        【讨论】:

        • 错误:来自 javadoc:返回一个 Field 对象数组,反映由该 Class 对象表示的类或接口声明的所有字段。这包括公共、受保护、默认(包)访问和私有字段,但不包括继承的字段
        猜你喜欢
        • 1970-01-01
        • 2011-08-20
        • 2013-08-15
        • 1970-01-01
        • 2020-08-04
        • 1970-01-01
        • 2021-01-26
        • 2011-10-06
        • 1970-01-01
        相关资源
        最近更新 更多