我预计在下面的代码中两个 put 操作都会抛出 NullPointerException,但实际上 lambda 表达式工作正常,而只是方法引用抛出 NPE。
public static void main(String... args) {
Object object = null;
Map<String, FuncInterface> map = new HashMap<>();
map.put("key1", () -> object.notify()); // works
map.put("key2", object::notify); // throws NPE
}
@FunctionalInterface
private interface FuncInterface {
public void someAction();
}
有什么区别?
lambda 在被调用时被评估:如果你调用 map.get("key1").someAction()
你会得到一个 NPE。
方法引用在创建时进行评估,即当您第一次编写 object::notify
时,它会立即抛出 NPE。
特别是,the JLS 15.13.3状态:
Evaluation of a method reference expression is distinct from invocation of the method itself.
First, if the method reference expression begins with an ExpressionName or a Primary, this subexpression is evaluated. If the subexpression evaluates to null, a NullPointerException is raised, and the method reference expression completes abruptly.