Reputation: 599
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?
Upvotes: 6
Views: 547
Reputation: 5585
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.
Upvotes: 3
Reputation: 599
https://bugs.openjdk.java.net/browse/JDK-8131323 explains why that happens. Method references work differently from lambdas, the method reference (not the method itself) is not evaluated lazily as it would be in a lambda.
Upvotes: 3