Java方法引用抛出NPE

jhe*_*eyd 6 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

MenuBarController是一个接口,其实现是setController在创建MenuBar之后设置的.代码抛出NullpointerException,menu.add(createMenuItem("Report", controller::writeReport))只能由此引起controller::writeReport.如果我用lambda代替它,就像() -> controller.writeReport()没有NPE 一样.

1.为什么controller::writeReport抛出NPE?

为什么lambda不投掷NPE?

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

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

Ian*_*ird 3

controller::writeReport抛出 NPE,因为controller在评估该行时为 null。

() -> controller.writeReport()不会抛出 NPE,因为在运行 lambda 时,controller已经给定了一个值。

  • 如果您将 lambda 写为 `() -> this.controller.writeReport()` 并带有显式接收器(这就是 lambda 的含义),这一点会更加明显。然后就可以更容易地看到 lambda 捕获的是“this”,而不是“controller”,这就是两者行为不同的原因。 (2认同)