【问题标题】:NullPointerException : Overriding constructor calling method of Base class in Derived classNullPointerException:在派生类中重写基类的构造函数调用方法
【发布时间】:2013-04-13 09:48:29
【问题描述】:

我有这个代码 sn-p:

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

【问题讨论】:

    标签: java nullpointerexception


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的回答。关于stackTrace 的另一件事是Derived.&lt;init&gt; 意味着它调用构造函数?为什么它被命名为&lt;init&gt;
    • @MohammadFaisal 是的,Derived.&lt;init&gt;Derived 的构造函数。
    【解决方案2】:

    您给出的代码是一个反模式。我们绝不应该调用处理来自 constructor 的字段的方法,原因很简单,因为它可能会产生意外结果

    从您的代码中,您正尝试在 Derived 构造函数中初始化一个名为 bar 的字段。现在,当你说Base b = new Derived() 时,调用方式如下

    1. 基础静态初始化器——如果你有
    2. 派生静态初始化器——如果你有

    3. 基本块初始化器——如果你有

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

    5. 派生块初始化器——如果你有

    6. 派生构造函数 --> 这是你初始化 bar 的地方

    现在由于运行时多态性,在第 4 项中,当调用 Derivedmethod() 时,bar 尚未初始化为值 "bar" (因为初始化发生在第 6 号),NPE 发生

    【讨论】:

      猜你喜欢
      • 2011-03-05
      • 2016-07-19
      • 1970-01-01
      • 2011-03-20
      • 2018-07-16
      • 2018-07-21
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      相关资源
      最近更新 更多