方法参考和lambda之间的区别

new*_*wur 3 java lambda

我希望两个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();
}
Run Code Online (Sandbox Code Playgroud)

有什么不同?

ass*_*ias 6

lambda在被调用时被评估:如果你打电话给map.get("key1").someAction()你,你会得到一个NPE.

方法引用在创建时进行评估,即在您第一次写入时object::notify,直接抛出NPE.

特别是,JLS 15.13.3规定:

方法引用表达式的评估不同于方法本身的调用.
首先,如果方法引用表达式以ExpressionName或Primary开头,则计算此子表达式.如果子表达式的计算结果为null,则会引发NullPointerException,并且方法引用表达式会突然完成.