NullPointerException:覆盖Derived类中的Base类的构造函数调用方法

时间:2013-04-13 09:48:30

标签: java nullpointerexception

我有这段代码:

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)

我无法理解为什么NullPointerExceptionstackTrace例外。有人可以帮我理解吗?

您可以查看代码here

2 个答案:

答案 0 :(得分:6)

new Derived()创建一个Derived对象,这意味着首先调用它的超类构造函数,然后调用method - 但是你已经覆盖method所以它是孩子被调用的那个方法的版本。在该方法中,您调用尚未初始化的bar.length

结论:在构造函数中调用可覆盖的方法几乎不是一个好主意。

答案 1 :(得分:2)

您提供的代码是 反模式 。我们永远不应该调用处理constructor字段的方法,原因很简单,因为它可能会产生意外结果

在您的代码中,您正在尝试在bar构造函数中初始化名为Derived的字段。现在当你说Base b = new Derived()时,呼叫以下列方式发生

  1. 基础静态初始化程序 - 如果您有
  2. 派生的静态初始化程序 - 如果您有

  3. 基本块初始化程序 - 如果您有

  4. 基础构造函数 - &gt;这是 你打电话的地方method()

  5. 派生块初始化程序 - 如果您有

  6. 派生构造函数 - &gt; 这是您初始化栏的地方
  7. 现在由于运行时多态性,在第4号中,当Derived的{​​{1}}被调用时,method()尚未初始化值bar(因为初始化发生在第6号),NPE发生

相关问题