Java反射:查找子类的字段

时间:2010-01-31 15:46:47

标签: java reflection

我有一个像这样的类层次结构:(=>表示“是”的子类“)

anonymous instance class => abstract class => generic abstract class

或更简洁:

C => B => A

执行时,“C”调用“A”方法之一。在“A”中的该方法中,我想使用反射来查找在类“B”中定义的对象的受保护字段。 (所以这些是“C”和“B”可以看到的字段,但不是“A”。)

如何使用Java反射执行此操作?如果我在A& A之间添加一些东西,我该怎样才能面向未来呢? B或B& C 1

4 个答案:

答案 0 :(得分:12)

您必须在对象类的继承层次结构中的每个类上重复使用getDeclaredFields()(通过getSuperclass())。

但是,你的计划听起来像是对遗传概念的恶意违反。面向未来的最佳方法是完全避免这种事情。

答案 1 :(得分:1)

Field[] fields = getClass().getSuperclass().getDeclaredFields();

然后迭代这些字段并获得你想要的字段。

如果您的层次结构增长,您可以将上述内容转换为对getSuperclass()getSuperclass() != Object.class)的递归调用,从而收集所有超类的所有字段。

答案 2 :(得分:1)

据我所知,没有办法反过来了解Java中的“子类”。难道更好的解决方案是在A上创建一个B必须实现的抽象方法,而不是调用它吗?

public class A {
   //other stuff here
   protected void abstract mySubMethod();
   //other stuff here
}

修改 如果我误解了你的问题,并且你真的想知道父类,那么是:getDeclaredFields()是正确的反射方法,正如其他海报所提到的那样。

其他编辑: 我不想继续修改这个答案,但...... 一般来说,如果您尝试授予父类的访问权限,那么“正确”和“未来证明”的方法是创建抽象方法,即getter或setter(如果需要,甚至更复杂),然后孩子们尊重与否,并酌情作出回应。

话虽如此,你可以做其他人所说的事情:

getClass().getParentClass().getDeclaredFields()

但是,只有在C总是直接从B继承的情况下,这才有效。反思就是它本质上是棘手而具体的。我必须在我正在进行的项目上做很多事情(不要问,相信我,你不想知道),我尽可能避免它。除非A有充分的理由需要受保护的字段并且它正在发现有关它们的信息,否则您可能希望使用抽象方法。我还要提出,你很可能用抽象方法解决了另一个问题,但这可能有点困难。

答案 3 :(得分:0)

Java 8+的递归方法示例

static final Field[] getDeclaredFields(Class clazz) {
    final Field[] fields = clazz.getDeclaredFields();

    if ( clazz.getSuperclass() != Object.class ) {
        final Field[] pFields = getDeclaredFields(clazz.getSuperclass());
        final Field[] allFields = new Field[fields.length + pFields.length];
        Arrays.setAll(allFields, i -> (i < pFields.length ? pFields[i] : fields[i - pFields.length]));
        return allFields;
    } else
        return fields;
}