gpt4 book ai didi

java - 为什么等效的 lambda 表达式和方法引用在捕获静态字段值时表现不同?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:43:06 26 4
gpt4 key购买 nike

我对 Java lambda 和方法引用行为有点困惑。例如,我们有这段代码:

import java.util.function.Consumer;

public class Main {

private static StringBuilder sBuilder = new StringBuilder("1");

public static void main(String[] args) {
Consumer<String> consumer = s -> sBuilder.append(s);
sBuilder = new StringBuilder("2");
consumer.accept("3");
System.out.println(sBuilder);
}

}

输出:

23

这按预期工作,但如果我们替换

s -> sBuilder.append(s)

sBuilder::append

输出将是:

2

您有什么想法可以解释吗?这不是一样的东西吗?谢谢。

最佳答案

在 lambda 表达式中,sBuilder 字段被捕获,但未被计算。它只会在相应的函数接口(interface)方法被调用时被评估。此时,sBuilder 引用创建并分配给字段的新实例

sBuilder = new StringBuilder("2");

在方法引用中,立即评估sBuilder 字段以生成Consumer 实例。该值引用在静态初始化程序中创建的实例

private static StringBuilder sBuilder = new StringBuilder("1");

Consumer 将在该消费者上运行。您打印新的。


来自 Java 语言规范,关于 Run-Time Evaluation of Method References

The body of an invocation method depends on the form of the method reference expression, as follows:

If the form is ExpressionName :: [TypeArguments] Identifier or Primary :: [TypeArguments] Identifier, then the body of the invocation method has the effect of a method invocation expression for a compile-time declaration which is the compile-time declaration of the method reference expression. Run-time evaluation of the method invocation expression is as specified in §15.12.4.3, §15.12.4.4, and §15.12.4.5, where:

  • The invocation mode is derived from the compile-time declaration as specified in §15.12.3.

  • The target reference is the value of ExpressionName or Primary, as determined when the method reference expression was evaluated.

  • The arguments to the method invocation expression are the formal parameters of the invocation method.

关于java - 为什么等效的 lambda 表达式和方法引用在捕获静态字段值时表现不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37979731/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com