java反射中getfields和getdeclaredfields的区别是什么

de90aj5v  于 2021-06-26  发布在  Java
关注(0)|答案(4)|浏览(345)

我有点搞不懂 getFields 方法和步骤 getDeclaredFields 方法。
我读到了 getDeclaredFields 允许您访问类的所有字段 getFields 仅返回公共字段。如果是这样的话,你为什么不一直用 getDeclaredFields ?
有人能详细说明一下这一点,并解释一下这两种方法之间的区别,以及你什么时候/为什么要用一种方法而不是另一种方法?

t2a7ltrp

t2a7ltrp1#

来自java反射教程:

zz2j4svz

zz2j4svz2#

如前所述, Class.getDeclaredField(String) 只从远处看田野 Class 你称之为。
如果你想搜索 FieldClass 在层次结构中,可以使用以下简单函数:

/**
 * Returns the first {@link Field} in the hierarchy for the specified name
 */
public static Field getField(Class<?> clazz, String name) {
    Field field = null;
    while (clazz != null && field == null) {
        try {
            field = clazz.getDeclaredField(name);
        } catch (Exception e) {
        }
        clazz = clazz.getSuperclass();
    }
    return field;
}

这对于找到一个 private 例如,来自超类的字段。另外,如果要修改其值,可以如下使用:

/**
 * Sets {@code value} to the first {@link Field} in the {@code object} hierarchy, for the specified name
 */
public static void setField(Object object, String fieldName, Object value) throws Exception {
    Field field = getField(object.getClass(), fieldName);
    field.setAccessible(true);
    field.set(object, value);
}
whhtz7ly

whhtz7ly3#

public Field[] getFields() throws SecurityException 返回一个数组,该数组包含反映该类对象所表示的类或接口的所有可访问公共字段的字段对象。返回的数组中的元素没有排序,也没有任何特定的顺序。如果类或接口没有可访问的公共字段,或者表示数组类、基元类型或void,则此方法返回长度为0的数组。
具体地说,如果这个class对象表示一个类,这个方法返回这个类及其所有超类的公共字段。如果这个类对象代表一个接口,这个方法返回这个接口及其所有超接口的字段。
此方法不反映数组类的隐式长度字段。用户代码应该使用类数组的方法来操作数组。 public Field[] getDeclaredFields() throws SecurityException 返回字段对象数组,该数组反映由该类对象表示的类或接口声明的所有字段。这包括public、protected、default(package)access和private字段,但不包括继承的字段。返回的数组中的元素没有排序,也没有任何特定的顺序。如果类或接口未声明任何字段,或者如果此类对象表示基元类型、数组类或void,则此方法返回长度为0的数组。
如果我需要所有父类的所有字段呢?需要一些代码,例如https://stackoverflow.com/a/35103361/755804:

public static List<Field> getAllModelFields(Class aClass) {
    List<Field> fields = new ArrayList<>();
    do {
        Collections.addAll(fields, aClass.getDeclaredFields());
        aClass = aClass.getSuperclass();
    } while (aClass != null);
    return fields;
}
yiytaume

yiytaume4#

获取字段()
所有的 public 整个类层次结构中的字段。
getdeclaredfields()
所有字段,无论其可访问性如何,但仅适用于当前类,而不是当前类可能继承的任何基类。
为了获取层次结构中的所有字段,我编写了以下函数:

public static Iterable<Field> getFieldsUpTo(@Nonnull Class<?> startClass, 
                                   @Nullable Class<?> exclusiveParent) {

   List<Field> currentClassFields = Lists.newArrayList(startClass.getDeclaredFields());
   Class<?> parentClass = startClass.getSuperclass();

   if (parentClass != null && 
          (exclusiveParent == null || !(parentClass.equals(exclusiveParent)))) {
     List<Field> parentClassFields = 
         (List<Field>) getFieldsUpTo(parentClass, exclusiveParent);
     currentClassFields.addAll(parentClassFields);
   }

   return currentClassFields;
}

这个 exclusiveParent 类以防止从中检索字段 Object . 可能是的 null 如果你真的想要 Object 领域。
为了澄清, Lists.newArrayList 来自Guava。

更新

仅供参考,上面的代码是在我的libex项目reflectionutils中发布在github上的。

相关问题