Java方法引用抛出NPE

Java方法引用抛出NPE,java,lambda,java-8,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("

所以我上了一节课

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
是一个接口,其实现是在创建菜单栏后通过
setController
设置的。代码在
菜单中抛出NullpointerException。添加(createMenuItem(“Report”,controller::WriterReport))
这只能由
控制器::WriterReport
引起。如果我用类似于controller.writeReport()的lambda替换它,则不会抛出NPE

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

2。为什么lambda不投掷NPE?

有趣的是:如果在使用lambda运行lambda一次之后,使用之前使用的方法引用替换lambda,则不会抛出更多的NPE


有人知道为什么会这样吗?一些javac/eclipse的怪异之处?

解释了为什么会发生这种情况。方法引用的工作方式与lambda不同,方法引用(而不是方法本身)不会像在lambda中那样延迟求值。

controller::writeReport
抛出NPE,因为求值行时
controller
为空


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

NPE的调用堆栈是什么?什么是null?此错误报告看起来很相关:
controller::writeReport抛出NPE?
,因为
controller
为null。您正试图在null对象->NPE上引用一个方法。请注意,当使用Eclipse4.4.1编译时,它在没有NPE的情况下运行!如果将lambda编写为This.controller.writeReport(),并带有显式接收器(这就是lambda的含义),则这一点更为明显。这样就更容易看到lambda捕获的是
这个
,而不是
控制器
,这就是两者行为不同的原因。