当前位置: 首页 > 知识库问答 >
问题:

为什么忽略实例变量“Lambda表达式中使用的变量必须是最终的或有效的最终的”警告[重复]

南宫奇思
2023-03-14

我正在研究java 8流,我唯一的问题是理解lambdas为什么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
    }
}

共有2个答案

徐英锐
2023-03-14

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

百里海超
2023-03-14

有效的最终规则仅适用于局部变量而不适用于全局变量,因此,当您更改全局变量时,第一种情况不会出现编译错误。

如果它有助于捕获实例变量,则可以将其视为捕获最终的局部变量,这样就不会出现编译错误。

《Java-8在行动》一书对此限制有一个有效的解释,如下所示:

你可能会问自己为什么局部变量有这些限制。首先,实例和局部变量在幕后的实现方式有一个关键的区别。实例变量存储在堆栈上,而局部变量存在堆栈上。如果lambda可以直接访问局部变量,并且lambda在线程中使用,那么使用lambda的线程可以在分配变量的线程释放变量后尝试访问变量。因此,Java实现了对自由局部变量的访问,作为对其副本的访问,而不是对原始变量的访问。

如果局部变量只被分配一次,这没有任何区别,因此有限制。其次,这种限制也不鼓励改变外部变量的典型命令式编程模式。

 类似资料:
  • 问题内容: 这个问题已经在这里有了答案 : 为什么在匿名类中只能访问最终变量? (15个答案) 为什么实例变量“忽略Lambda表达式中使用的变量必须是最终变量或实际上是最终变量”警告[重复] (2个答案) Lambdas:局部变量不需要最终变量,实例变量不需要 (10个答案) 2年前关闭。 当我编写此代码时,我收到一个编译时错误,该错误是: “ lambda中的变量必须是final或有效的fin

  • 我正在研究Java8流,我理解lambdas的唯一问题是为什么lambdas中有效的最后警告被忽略,例如实例(和静态)变量。我似乎在网上找不到任何关于它的参考,因为大多数页面只会谈论“有效最终”的定义。

  • 我正在尝试从pojo创建一个函数,该函数在以下意义上使用细节类值的求和: 但是不知道为什么这一行< code > sum = sum . add(detail . getvalue());引发此错误: 从lambda表达式引用的局部变量必须是final或有效final 你能告诉我我做错了什么吗?谢了。

  • 在Java8中,Java设计者提出了一个有效的final变量的概念,即一个如果被“final”追加就不会给编译器带来错误的变量。我的问题是,这个新提出的“有效最终”概念比经典的“最终”提供了什么?作为一名Java开发人员,我实际上得到了什么好处?

  • 我试图在中的forloop中更新,因为导致一个新的ComppletableFuture实例,我需要将其重新分配给一个新变量以更新,但我不太确定如何

  • 我读到了这个关于不可变对象的问题,留下了一个关于不可变对象和final字段的问题: 为什么我们需要不可变类中的实例变量成为最终变量? 例如,考虑这个不可变类: 如果在上面的代码中没有设置方法,并且实例变量只在构造函数中设置,那么为什么需要将实例变量声明为final?