使用lambda 表达式常常会遇到上面的编译错误。
首先需要知道什么是最终变量或实际上的最终变量:
最终变量(final) :用final关键字修饰的变量,特点是一旦赋值就不能被修改。
实际上的最终变量(effectively final) :没有inal关键字修饰,但是只有一次赋值的变量。
例如这么写就不是实际上的最终变量:
String name = "one";
name = "two"; // 变量被修改,不再是"实际上的最终变量"
Java只所以做这个限制,是为了保障线程安全问题 和**语义一致性问题,**最核心的问题这种场景下,Java是传值调用,lambda使用的是变量的副本。这样解决该问题有两个办法:
1、改为按引用调用。
使用类、数组做参数
2、使用个中间变量来存值
for(int i=0; i<10; i++) { Runnable r = () -> System.out.println(i); } 这样会报错,因为i是变化的。
这样改下就OK:
for(int i=0; i<10; i++) {
int temp = i; // 临时变量,每次循环都是新的、只赋值一次
Runnable r = () -> System.out.println(temp);
}