为什么实例变量会忽略“ Lambda表达式中使用的变量必须是最终变量或实际上是最终变量”警告

use*_*339 3 lambda java-8 java-stream

我正在研究Java 8流,我唯一的问题是了解lambda,这是为什么对于instance(和static)变量,lambdas中有效的最终警告会被忽略的原因。我似乎无法在网上找到任何提及它,因为大多数网页将刚才讲的是“有效决赛”的定义。

public class LambdaTest {

    int instanceCounter = 0;

    public void method() {
        int localCounter = 0;
        instanceCounter = 5; //Re-assign instance counter so it is no longer effectively final

        Stream.of(1,2,3).forEach(elem -> instanceCounter++); //WHY DOES THE COMPILER NOT COMPLAIN HERE
        Stream.of(1,2,3).forEach(elem -> localCounter++); //Does not compile because localCounter is not effectively final
    }
}
Run Code Online (Sandbox Code Playgroud)

Ous*_* D. 6

为什么局部变量会编译错误?

有效的最终规则只适用于局部变量,而不是全局变量,由于这个原因,有一个为你突变的全局变量第一个场景中没有编译错误。

如果它可以帮助捕捉一个实例变量可以被看作是捕捉最后的局部变量这个所以没有编译错误。

为什么会有这样的限制?

Java-8 in Action》一书对此限制有一个有效的解释,其内容如下:

您可能会问自己,为什么局部变量具有这些限制。首先,幕后实现实例和局部变量的方式存在关键差异。实例变量存储在堆中,而局部变量存在于堆栈中。如果lambda可以直接访问局部变量并且该lambda在线程中使用,则使用lambda的线程可以在分配变量的线程将其释放后尝试访问该变量。因此,Java将对自由本地变量的访问实现为对其副本的访问,而不是对原始变量的访问。

如果仅将局部变量分配给限制一次,则这没有区别。其次,该限制也不利于使外部变量发生变异的典型命令式编程模式。


Eug*_*ene 4

我们往往会忘记,您正在捕获的instanceCounter实际上是最终的结果。至于为什么需要这个,答案显然在这里this.instanceCounterthis


归档时间:

查看次数:

4041 次

最近记录:

6 年,2 月 前