Variable used in lambda expression should be final or effectively final
时间: 2023-09-03 21:25:59 浏览: 97
### 回答1:
这个错误是因为在 Java 8 中,Lambda 表达式中访问的局部变量必须是 final 或 effectively final,也就是说一旦被赋值就不能再改变。
如果你想在 Lambda 表达式中使用一个非 final 的局部变量,可以通过将其包装成一个对象来实现。例如:
```
List<String> messages = ...;
AtomicInteger counter = new AtomicInteger();
messages.forEach(msg -> {
System.out.println(counter.getAndIncrement() + ": " + msg);
});
```
在这个例子中,我们使用了一个 AtomicInteger 对象来替代了一个简单的 int 变量。这样就可以在 Lambda 表达式中对其进行修改,而不会导致编译错误。
### 回答2:
在 lambda 表达式中使用的变量应该是 `final` 或者是“有效 final”的。这是因为 lambda 表达式中的局部变量在编译时就被转换为了一个成员变量,而成员变量必须是 `final` 或者是“有效 final”的。
`final` 变量是指一旦赋值后就不能再修改的变量。而“有效 final”变量是指虽然没有被声明为 `final`,但是在使用前只被赋值一次,并且在 lambda 内部没有发生修改。
这个要求是因为 lambda 表达式可以在一个不同的线程中执行。如果在 lambda 中使用的变量没有被限制为 `final` 或“有效 final”,那么在多线程的环境下,可能会发生竞态条件(race condition)问题。为了避免这种情况,Java 强制要求在使用 lambda 表达式中的局部变量时使用 `final` 或“有效 final”变量。
例如,下面的代码中,如果将 `num` 声明为 `final` 或者只被赋值一次,并且在 lambda 中没有被修改,那么程序会正常执行。若不符合上述条件,则会报编译错误:
```java
int num = 10;
Thread t = new Thread(() -> {
System.out.println(num);
});
t.start();
```
阅读全文