所以我上了一堂课
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奇怪吗?
答案 0 :(得分:3)
https://bugs.openjdk.java.net/browse/JDK-8131323解释了为什么会这样。方法引用与lambdas的工作方式不同,方法引用(不是方法本身)不会像在lambda中那样懒惰地进行评估。
答案 1 :(得分:3)
controller::writeReport
会抛出一个NPE,因为在评估该行时controller
为空。
() -> controller.writeReport()
不会抛出NPE,因为在运行lambda时,controller
已被赋予值。