我有这段代码:
class Base {
public Base() {
method();
}
void method() {
System.out.println("In Base");
}
}
class Derived extends Base {
private String bar;
public Derived() {
bar="bar";
}
public void method() {
System.out.println(bar.length());
}
public static void main(String[] args) {
Base base=new Derived();
base.method();
}
}
在执行代码时,我得到了一个例外:
Exception in thread "main" java.lang.NullPointerException
at Derived.method(Main.java:22)
at Base.<init>(Main.java:5)
at Derived.<init>(Main.java:17)
at Derived.main(Main.java:27)
我无法理解为什么NullPointerException
和stackTrace
例外。有人可以帮我理解吗?
您可以查看代码here。
答案 0 :(得分:6)
new Derived()
创建一个Derived
对象,这意味着首先调用它的超类构造函数,然后调用method
- 但是你已经覆盖method
所以它是孩子被调用的那个方法的版本。在该方法中,您调用尚未初始化的bar.length
。
结论:在构造函数中调用可覆盖的方法几乎不是一个好主意。
答案 1 :(得分:2)
您提供的代码是 反模式 。我们永远不应该调用处理constructor
字段的方法,原因很简单,因为它可能会产生意外结果。
在您的代码中,您正在尝试在bar
构造函数中初始化名为Derived
的字段。现在当你说Base b = new Derived()
时,呼叫以下列方式发生
派生的静态初始化程序 - 如果您有
基本块初始化程序 - 如果您有
基础构造函数 - &gt;这是
你打电话的地方method()
派生块初始化程序 - 如果您有
现在由于运行时多态性,在第4号中,当Derived
的{{1}}被调用时,method()
尚未初始化值bar
(因为初始化发生在第6号),NPE发生