Java方法引用抛出NPE

时间:2015-11-05 20:49:27

标签: java lambda java-8

所以我上了一堂课

public class MenuBar extends JMenuBar {

    MenuBarController controller;

    public MenuBar() {
        JMenu menu = new JMenu("File");
        menu.add(createMenuItem("Report", controller::writeReport));
        menu.add(createMenuItem("Save", controller::save));
        menu.add(createMenuItem("Import", controller::importFile));
        menu.add(createMenuItem("Clear DB", controller::clearDatabase));
        add(menu);
    }

    public void setController(MenuBarController controller) {
        this.controller = controller;
    }
}

MenuBarController是一个接口,其实现是在创建MenuBar后通过setController设置的。代码在menu.add(createMenuItem("Report", controller::writeReport))处抛出NullpointerException,这只能由controller::writeReport引起。如果我用像() -> controller.writeReport()之类的lambda替换它,则不会抛出NPE。

1。为什么controller::writeReport会抛出NPE?

2。为什么lambda不会抛出NPE?

有趣的部分是:如果我使用lambda运行一次后使用之前使用的方法引用替换lambda,则不会再抛出NPE。

任何人都知道为什么会这样?一些javac / eclipse奇怪吗?

2 个答案:

答案 0 :(得分:3)

https://bugs.openjdk.java.net/browse/JDK-8131323解释了为什么会这样。方法引用与lambdas的工作方式不同,方法引用(不是方法本身)不会像在lambda中那样懒惰地进行评估。

答案 1 :(得分:3)

controller::writeReport会抛出一个NPE,因为在评估该行时controller为空。

() -> controller.writeReport()不会抛出NPE,因为在运行lambda时,controller已被赋予值。

相关问题