继承,超级()的NullPointerException概念

时间:2014-04-16 02:52:16

标签: java inheritance

基类:

public class Base {
    private String baseMessage = "Hello!";

    public Base() {
        printMessage();
    }

    public void printMessage() {
        System.out.println(baseMessage.toString());
    }
}

派生类:

public class Derived extends Base {
    private String derivedMessage = "World!";

    public Derived () {
        super();

    }

    @Override
    public void printMessage() {
        super.printMessage();
        System.out.println(derivedMessage.toString());
    }


    public static void main(String[] args) {
//      new Base();
        new Derived();
    }
}

当我跑步时

new Base();

我得到了预期的输出:

Hello!

当我跑步

new Derived();

我得到了

Hello!
Hello!

然后是NullPointerException。这对我来说似乎有点奇怪。我不知道为什么它打印出来然后抛出一个nullpointerexception,而不是直接抛出它。也许是Eclipse,我不知道。

这里的基本概念是什么?

1 个答案:

答案 0 :(得分:5)

在您阅读本文之前,请阅读

子类构造函数的主体被编译为类似

的内容
public Derived () {
    super();
    initializeInstanceFields(); 
    // all instance fields are initialized either to their default value
    // or with their initialization expression
}

换句话说,当Derived#printMessage()由于super构造函数的多态性而被调用时,Derived.derivedMessage仍然是null


这是一步一步:

new Derived();

调用Derived构造函数

public Derived () {
    super();
}

调用super构造函数

public Base() {
    printMessage();
}

此处,在printMessage()之前,这个班级'实例字段已初始化,因此baseMessage获取"Hello!"的值。调用printMessage()时,因为thisDerived对象而Derived会覆盖这些方法,所以会调用其实现。

@Override
public void printMessage() {
    super.printMessage();
    System.out.println(derivedMessage.toString());
}

这会调用super实现

public void printMessage() {
    System.out.println(baseMessage.toString());
}

打印

Hellow!

该方法返回Derived#printMessage并尝试在toString()上调用derivedMessaged,但正如我之前解释的那样,derivedMessage没有&{39}。尚未初始化,因此它是null。取消引用null会导致NullPointerException

这就是为什么你不从构造函数调用可覆盖的方法。