为何Java中已创建的Lambda函数会因外部变量变更输出不同结果?
Lambda随外部状态变化输出不同结果的原因及解决方法
你的问题核心在于:Lambda捕获的不是value的当前值,而是mine对象的引用,每次执行Lambda时都会实时读取该对象的value字段,而非创建Lambda时的固定快照。
原代码的执行逻辑
- 当你调用
a.createFunction()返回Lambda时,这个Lambda并没有保存当时value=100的副本,而是持有对a这个mine实例的引用; - 第一次调用
add.apply(5),Lambda读取a当前的value=100,计算得5+100=105; - 调用
a.setValue(10)修改了a对象的value字段; - 第二次调用
add.apply(5),Lambda读取a最新的value=10,计算得5+10=15。
这就导致了相同输入得到不同输出,违背了你预期的纯函数特性。
解决方案:捕获固定值快照
要让Lambda使用创建时的value值,需要在创建Lambda前,把当前的value赋值给一个局部变量(该变量会被Lambda捕获为不可变的快照)。修改createFunction方法如下:
public class mine { int value; public Function<Integer, Integer> createFunction() { int capturedValue = this.value; // 保存当前value的快照 return (m) -> m + capturedValue; } public void setValue(int value) { this.value = value; } }
修改后,无论后续如何修改a.value,Lambda都会使用创建时捕获的capturedValue值,两次调用add.apply(5)都会输出105,符合纯函数相同输入返回相同输出的要求。
内容的提问来源于stack exchange,提问作者Deenadayalan
相关产品推荐
相关产品推荐

