正如@Voo 所说,
您的问题是关于在已经完全构造的对象上调用虚拟方法。在构造对象上调用虚方法的众所周知的缺点是众所周知的,但在这里不适用
来自Effective Java 2nd Edition,第 17 项:设计和记录继承,否则禁止它:
一个类必须遵守更多的限制以允许继承。构造函数不得直接或间接调用可覆盖的方法。如果您违反此规则,将导致程序失败。超类构造函数在子类构造函数之前运行,因此子类中的覆盖方法将在子类构造函数运行之前被调用。如果覆盖方法依赖于子类构造函数执行的任何初始化,则该方法将不会按预期运行。
在对象构造期间调用可覆盖的方法可能会导致使用未初始化的数据,从而导致运行时异常或意外结果。
构造函数必须只调用最终或私有的方法
您可以使用静态工厂方法来解决必须从Bar class
.
Effective Java,第 1 项:考虑静态工厂方法而不是构造函数
类允许客户端获取自身实例的常规方法是提供公共构造函数。还有另一种技术应该成为每个程序员工具包的一部分。一个类可以提供一个公共静态工厂方法,它只是一个返回类实例的静态方法。
所以,你去有界面:
public interface Foo {
void doFoo();
}
和实施:
public class FooImpl implements Foo {
@Override
public void doFoo() {
//.. Do important code
}
}
要使用您的工厂方法创建您的类,您可以通过以下方式工作:
private Foo fi
使用接口而不是来定义类的变量,private FooImpl fi
在具体类型上使用接口是良好封装和松散耦合代码的关键。
将您的默认构造函数设为私有,以防止在外部实例化您的类。
private Bar() { // 防止实例化 }
删除对构造函数中存在的方法的所有调用。
创建你的静态工厂方法
最后你得到一个Bar
带有工厂方法的类,如:
public class Bar {
private Foo fi;
private Bar() {// Prevents instantiation
fi = new FooImpl();
}
public static Bar createBar() {
Bar newBar = new Bar();
newBar.fi.doFoo();
return newBar;
}
}
我的老板说:“声纳警告是关于症状的,而不是关于疾病的。能治好病最好。” !