我有一个像这样的类层次结构:(=>表示“是”的子类“)
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
答案 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;
}