Java中lambda与方法引用的执行时机为何存在差异?
根本原因:Java语言规范对二者的求值时机定义不同
核心差异来自两类表达式的求值规则,具体如下:
- lambda表达式的求值是惰性的
你代码里的() -> i.close()属于无参lambda,创建VoidSupplier实例的时候只会捕获变量i的引用,不会立刻执行lambda体里的逻辑,也不会提前对i进行求值。只有当VoidSupplier的apply()方法被调用时,才会读取i的值、执行i.close()逻辑,而这一步的调用已经被execute方法里的try-catch包裹,抛出的空指针异常会被内部捕获处理,不会影响后续代码执行。 - 绑定实例的方法引用会提前对实例求值
你代码里的i::close属于「引用特定对象的实例方法」类型的方法引用,Java规范明确要求这类方法引用在表达式求值阶段(也就是作为参数传给execute方法之前,还没进入execute的逻辑),就必须先对::左侧的实例表达式进行求值,拿到实例对象后绑定到生成的函数式接口实例上。这一步如果实例为null,会直接抛出NullPointerException,这个异常没有被execute的try-catch覆盖,自然会导致后续代码无法运行。
内容的提问来源于stack exchange,提问作者Guo
相关产品推荐
相关产品推荐

