Java Method Reference

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 creating the MenuBar. The code throws a NullpointerException in menu.add(createMenuItem("Report", controller::writeReport)) , which can only be called controller::writeReport . If I replace this with lambda, for example () -> controller.writeReport() , NPE will not be thrown.

1. Why controller::writeReport throw NPE?

2. Why doesn't lambda throw NPE?

The funny part: if I replaced the lambda with a reference to the method used before I ran it once with the lambda, NPE will no longer be added.

Has anyone understood why this could be? Some weird javac / eclipse?

+5
source share
2 answers

controller::writeReport throws NPE because controller is null when the line is evaluated.

() -> controller.writeReport() does not throw NPE, because by the time the controller lambda was executed, a value was set.

+3
source

https://bugs.openjdk.java.net/browse/JDK-8131323 explains why this is happening. Method references work differently than lambdas, a method reference (and not the method itself) is not evaluated lazily, as it would in lambdas.

+3
source

Source: https://habr.com/ru/post/1235324/


All Articles