Java 8
我有点感到困惑,因为我们无法从构造函数中调用虚方法。陷阱是我们可以超载并崩溃。但是,如果我们从 最终 类的构造函数中调用它,该怎么办呢?像这样:
public final class MyClass implements MyInterface {
private final Object[] arr;
public MyClass(){
Object[] arr;
//init arr
this.arr = arr;
//Now we have to preprocess it
preprocess();
}
@Override
public void preprocess(){
//impl
}
public int count(){
//impl
}
}
public interface MyInterface{
void preprocess();
int count();
}
在构造函数中调用虚方法还有其他缺陷吗?当然,我可以将预处理提取到静态方法中,然后从两者中调用它,但它看起来有点乱。我想保持代码尽可能干净。
答案 0 :(得分:4)
从构造函数调用方法时应始终小心,因为对象构造尚未完成。即使对于final
和private
方法也是如此,这些方法无法被子类覆盖。
示例:
public class Test {
public static void main(String[] args) {
new Sub().test();
}
}
class Base {
int b;
Base() {
test();
this.b = 1;
}
void test() {
System.out.println("Hello from Base. b = " + this.b);
}
}
class Sub extends Base {
int s;
Sub() {
test();
this.s = 2;
}
@Override
void test() {
System.out.println("Hello from Sub. b = " + this.b + ", s = " + this.s);
}
}
<强>输出强>
Hello from Sub. b = 0, s = 0
Hello from Sub. b = 1, s = 0
Hello from Sub. b = 1, s = 2
test()
被调用3次:来自Base
构造函数,Sub
构造函数和main()
。
正如您所看到的,即使第一次调用时字段b
尚未初始化。
那么,这样做是否违法?第
你应该避免吗?是的。
只需明确(例如javadoc)可以在部分初始化的对象上调用该方法。