【问题标题】:Java8 Effectively Final compile time error on non final variableJava8在非最终变量上有效地最终编译时错误
【发布时间】:2015-08-28 10:23:12
【问题描述】:

我正在尝试将 java8 forEach 循环中的布尔变量更改为非最终的 true。但我收到以下错误:在封闭范围中定义的局部变量必须是最终的或有效的最终。

如何解决这个错误?

代码:

boolean required = false; 

这是我在函数中创建的变量。

现在当我试图改变它时:

   map.forEach((key, value) -> {
        System.out.println("Key : " + key + " Value : " + value);
        required = true;
    });

我收到错误消息:在封闭范围内定义的局部变量必须是最终的或有效的最终变量。

为什么会出现此错误以及如何解决?

【问题讨论】:

    标签: java lambda java-8


    【解决方案1】:

    您不能从 lambda 表达式的主体中更改局部变量。有几种方法可以解决这个问题:

    • 在这种特殊情况下,您可以只设置 boolean required = !map.isEmpty(); 而无需任何 lambda 表达式。如果您想根据某些条件进行设置,可以使用 Stream API:

      boolean required = map.entrySet().stream().anyMatch(entry -> ...);
      

      此解决方案是最优选的。

    • required 变量转换为封闭类的字段。

    • 最肮脏的方式:声明一个单元素数组:boolean[] required = {false};,然后设置这个元素:required[0] = true;

    【讨论】:

    • 类似这样的东西:最肮脏的方式:声明一个单元素数组:boolean[] required = {false};并设置此元素: required[0] = true;我实际上想这样做,但正如你所说,它看起来很脏。有没有其他方法可以更改 lambda 表达式中的局部变量 @tagirValeev
    • @Siddharth,实际上没有办法改变局部变量。在boolean[] required 的情况下,您不会更改局部变量,而是更改堆对象。
    • 只是为了增强我的知识,您能否解释一下您通过更改头部对象而不更改局部变量实际上是什么意思。 @tagirValeev
    • 一种比单元素数组稍微不那么难看的方法是使用AtomicBoolean,它可以通过set(boolean) 方法更改其值。
    • 是的,即使将布尔变量封装在一个类中并使用它也可以。 @dkatzel
    猜你喜欢
    • 1970-01-01
    • 2018-09-15
    • 2021-02-24
    • 1970-01-01
    • 2013-06-20
    • 1970-01-01
    • 1970-01-01
    • 2020-12-23
    • 1970-01-01
    相关资源
    最近更新 更多