Java:lambda 和方法引用有不同的执行时间吗?

Guo*_*Guo 3 java lambda method-reference

代码:

@FunctionalInterface
interface VoidSupplier {
    void apply() throws Exception;
}

void execute(VoidSupplier voidSupplier) {
    if (voidSupplier != null) {
        try {
            voidSupplier.apply();
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

调用execute使用lambda

@Test
public void testLambda() {
    InputStream i = null;
    execute(() -> i.close());       // use lambda
    System.out.println("output some message");  // will be executed
}
Run Code Online (Sandbox Code Playgroud)

调用execute使用方法参考

@Test
void testMethodReference() {
    InputStream i = null;
    execute(i::close);             //  use method reference
    System.out.println("output some message");   // will not be executed
}
Run Code Online (Sandbox Code Playgroud)

当使用拉姆达execute(VoidSupplier)将执行第一,和然后执行() -> i.close()
但使用方法参照i::close将被执行的第一,和然后执行execute(VoidSupplier)
为什么 lambda 和方法引用具有不同的执行时间?

Era*_*ran 5

execute(VoidSupplier voidSupplier)是一种方法。在执行此方法之前,必须评估其参数,无论它是 lambda 表达式还是方法引用。

lambda 表达式片段:

为了评估 lambda 表达式,不需要执行 lambda 表达式主体。因此,该表达式() -> i.close()不会引发异常。只有当execute被执行,被执行时NullPointerException才会抛出voidSupplier.apply(),并且你捕获那个异常,允许System.out.println被执行。

方法参考片段:

如果您使用空引用作为方法引用的左侧,则方法引用的评估将导致NullPointerException

JLS 15.3.3。方法参考的运行时评估

首先,如果方法引用表达式以 ExpressionName 或 Primary 开头,则计算此子表达式。如果子表达式的计算结果为 null,则会引发 NullPointerException,并且方法引用表达式会突然完成。如果子表达式突然完成,方法引用表达式也会出于同样的原因突然完成。

这意味着评估i::closethrows NullPointerException,并且execute()不会执行。由于您没有捕获此异常,System.out.println因此永远不会到达您的语句。


归档时间:

查看次数:

58 次

最近记录:

4 年,3 月 前