2

可能重复:
通过 Java 中的反射访问私有继承字段

您好,我遇到了 java 反射的 init 值问题。

我有简单的课

 public class A extends B {
     private String name;
 }

  public class B {
     private String superName;   
  }

而且我有简单的功能:

   public void createRandom(Class<T> clazz , List<String> classFields){


    try {
        T object = clazz.newInstance();
        for(String s : classFields){
            clazz.getDeclaredField(s);
        }

    } catch(Exception e){

    }

   }

我的功能做其他事情,但我有问题,因为我有错误:

java.lang.NoSuchFieldException: superName

如何使用反射设置所有类字段以及超类中的字段?

我有所有的类字段(也是继承的)并且我正在使用函数field.set(Object obj, Object value)但是这样我不能设置继承的类字段:/

我没有问题来获取我正在使用 Spring ReflectionUtils.doWithfield 的所有类字段。我将所有字段名称存储在 中List<String> classField,所以我知道所有 clazz 字段也继承了。但我的问题是如何为所有 clazz 字段设置值。

4

4 回答 4

7

如果我不得不猜测,我假设您在 A 类上调用此方法,并期望能够查看 B 类中声明的基础字段,如下所示:

A.class.getDeclaredField("superName");

情况并非如此,并且会抛出异常 ( java.lang.NoSuchFieldException)。反射不检查超类来查找字段或方法。因此,由于 classA没有定义superName,因此不会像这样使用反射找到它。但是,您可以修改代码以使其检查所有超类,直到它null作为超类到达,此时如果仍未找到它,则它肯定不存在。

这是一个例子:

public static Field findUnderlying(Class<?> clazz, String fieldName) {
    Class<?> current = clazz;
    do {
       try {
           return current.getDeclaredField(fieldName);
       } catch(Exception e) {}
    } while((current = current.getSuperclass()) != null);
    return null;
}

这是一个示例调用findUnderlying(A.class, "superName"):它会首先检查 A 类的字段。由于 A 没有它,所以 dowhile 然后转到它的超类,即 B (不为空,所以继续)。B 确实有它,因此它会返回该字段。如果 B 没有它,它将检查 Object,然后返回 null,因为 Object 没有超类。

于 2012-09-18T21:36:53.600 回答
6

您可以使用:

clazz.getSuperclass().getDeclaredField(s);

而不是(或除了一些try-catch):

clazz.getDeclaredField(s);

编辑:

要设置超类的值,请使用以下命令:

Field f = clazz.getSuperclass().getDeclaredField(s);
f.setAccessible(true); // Especially necessary if the field is not public
f.set(yourObject, theValue);
于 2012-09-18T21:40:57.803 回答
1

使用Class.getSuperclass()获取超类。然后使用超类,您可以获得它的字段。

于 2012-09-18T21:39:48.333 回答
-1

即使 A 从 B 扩展,它也不适用于 A 的实例,这是因为子类中无法访问私有成员。尝试将 superName 的访问权限更改为 protected ,如果它有效......

于 2012-09-18T21:36:04.770 回答