Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 方法参考和lambda之间的差异_Java_Lambda - Fatal编程技术网

Java 方法参考和lambda之间的差异

Java 方法参考和lambda之间的差异,java,lambda,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.no

我希望这两个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();
}
publicstaticvoidmain(字符串…参数){
Object=null;
Map Map=newhashmap();
map.put(“key1”,()->object.notify());//有效
map.put(“key2”,object::notify);//抛出NPE
}
@功能接口
专用接口{
公共行动();
}

区别是什么?

在调用lambda时对其进行评估:如果调用
map.get(“key1”).someAction()
,则会得到一个NPE

方法引用在创建时进行评估,即当您第一次编写
对象::notify
时,它会立即抛出一个NPE

特别是,缔约国:

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


我也试过你的代码,但都得到了NPE。@SunilSinghBora你在使用eclipse吗?是的。我在EclipseIDE中运行这段代码。这可能是一个bug-它的行为与javac/java所描述的一样。我称之为bug。在EclipseNeon.2中调试时,我没有发现此代码的任何异常。根据字节码,这两个函数都是通过INVOKEDYNAMIC/LambdaMetafactory.metafactory创建的。发生这样的事情时非常烦人。。。。。在命令行上使用javac/java,我得到了预期的异常……这是正确的。请原谅.net开发人员偶尔转向java,但由于对象没有标记为final,那么首先哪条规则允许编译(但当您实际分配一个对象时会抱怨,当您没有将实例分配给最终对象时,不会抱怨空引用);-)编辑:哦,必须是关于“有效地最终”的;没关系。我不确定我是否完全理解你的问题,但编译器不会进行空检查。您可以编写
对象o=null;o、 toString()如果需要:它将被编译。如果将
Object Object=null
更改为
Object Object=new Object()
,编译器将抱怨对象不是lambda中的最终对象。另一方面,当您将其标记为final但保持为
null
时,编译器不会抱怨
object::notify
,即null::notify。但是,是的,我只是在发布了我的“问题”后才注意到编译器确实检查了“有效最终”,所以行为不像我最初想的那样不一致。听起来对我来说是正确的答案。奇怪的是,许多教程建议使用方法引用而不是lambdas,却没有提到这种差异。更好的是没有区别…@newur此问答内容丰富: