So I got a class
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 is an interface whose implementation is set via setController after the MenuBar ist created. The code throws a NullpointerException at menu.add(createMenuItem("Report", controller::writeReport)) which can only be caused by controller::writeReport. If I replace this with a lambda like () -> controller.writeReport() no NPE is thrown.
1. Why does controller::writeReport throw an NPE?
2. Why doesn't the lambda throw an NPE?
The funny part is: If I replace the lambda with the method reference used before after I ran it once with the lambda, no more NPEs are thrown.
Anyone got any idea why that could be? Some javac / eclipse weirdness?
解决方案
controller::writeReport throws an NPE because controller is null when the line is evaluated.
() -> controller.writeReport() does not throw an NPE because by the time the lambda is run, controller has been given a value.