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捕获的是这个
,而不是控制器
,这就是两者行为不同的原因。