请考虑以下代码:
static int k;
public static void main(String[] args) {
int i = 0; i++;
new Thread( () -> {System.out.print(i); });
int[] j = new int[1]; j[0]++;
new Thread( () -> {System.out.print(j[0]); });
k = 0; k++;
new Thread( () -> {System.out.print(k); });
}
在第一种情况下,我得到一个错误"我在封闭范围内定义的局部变量必须是最终的或有效的最终"。我理解这个错误背后的基本原理:lambda表达式中的代码可能在不同的时间运行,其中i的值将不同,因此结果将与预期的不同。
我不明白的是:为什么我在第二和第三个例子中没有得到相同的错误,这些错误实际上是相同的?
编辑:关于为什么第一个案例是错误有很多问题。我的问题不同:我问为什么第二和第三种情况不被视为错误?
答案 0 :(得分:1)
第二个示例没有给出编译器错误,因为它满足有效的最终规则。标识符j
永远不会更改,因为始终指的是同一个数组,因此您可以在lambda语句块中访问它。执行操作j[0]++
正在改变数组的状态,但不会改变j
在内存中指向的位置,因此完全可以接受。
最后一个例子有效,因为变量k
是一个全局变量,它不必是有效的最终,也不是 final 。