【发布时间】:2017-03-14 14:27:19
【问题描述】:
我无法在类构造函数中使用继承进行反射。具体来说,我想获取所有属性值。
这是一个无效的简单实现的演示:
import java.lang.reflect.Field;
public class SubInitProblem {
public static void main(String[] args) throws IllegalAccessException {
Child p = new Child();
}
}
class Parent {
public int parentVar = 888888;
public Parent() throws IllegalAccessException {
this.showFields();
}
public void showFields() throws IllegalAccessException {
for (Field f : this.getClass().getFields()) {
System.out.println(f + ": " + f.get(this));
}
}
}
class Child extends Parent {
public int childVar = 999999;
public Child() throws IllegalAccessException {
super();
}
}
这将表明childVar 为零:
public int Child.childVar: 0
public int Parent.parentVar: 888888
因为它还没有初始化。
所以我想我不需要直接使用构造函数,而是让构造函数完成并然后使用showFields:
import java.lang.reflect.Field;
public class SubInitSolution {
public static void main(String[] args) throws IllegalAccessException {
SolChild p = SolChild.make();
}
}
class SolParent {
public int parentVar = 888888;
protected SolParent() {
}
public static <T extends SolParent> T make() throws IllegalAccessException {
SolParent inst = new SolParent();
inst.showFields();
return (T) inst;
}
public void showFields() throws IllegalAccessException {
for (Field f : this.getClass().getFields()) {
System.out.println(f + ": " + f.get(this));
}
}
}
class SolChild extends SolParent {
public int childVar = 999999;
public SolChild() throws IllegalAccessException {
}
}
但这不起作用,因为make 没有为子类返回正确的类型。 (所以问题是new SolParent();)。
解决此问题的最佳方法是什么? 我需要所有子类来执行showFields,但我不能依赖它们明确地执行它。
【问题讨论】:
-
在你的第二个例子中,为什么要实现
make方法?为什么不直接做new SolChild().showFields(); -
不要从构造函数中调用此类方法。它们不参与初始化,因此不属于构造函数。
-
@Mark 让每个构造函数调用某个方法,这个方法需要放在那个构造函数中。但是编译器不能让某人在他们的构造函数中添加特定的方法调用(即使他们扩展了你的类)。我有一种感觉,我们正面临着X/Y problem。
-
@Mark 一个更简单的替代方法是使用
init或start方法并记录在使用对象之前需要调用它的事实。所以基本上为这些类型的对象创建一个生命周期合约。 -
你不能使
SolParent()构造函数private。如果你这样做,子类是不可能的。
标签: java inheritance constructor java-8 static-typing