Ale*_*ara 5 java foreach lambda anonymous-inner-class
在Java中,我有以下代码
List<Integer> myList = new ArrayList<>();
for (int i=0;i<9;i++) {
myList.add(i);
}
Integer sum = 0;
myList.forEach(i -> {
sum = sum + i; // does not compile, sum needs to be final or effectively final
});
for(int i : myList) {
sum = sum + i; //runs without problems
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么我不能在lambda中改变sum的值?它与下面的for循环完全相同,或者我错了?有趣的是,如果我将main方法之外的整数和声明为静态,它也可以.谁能解释我为什么?
编辑:在另一个类似的问题Java 8支持闭包,答案似乎是:
它是向后兼容性和项目资源约束的组合.
但是,我仍然无法理解为什么它可以工作,如果我将数组和数组或我在main之外声明它.我还想了解下面的myList.forEach和for循环之间有什么区别,为什么一个有效,另一个没有.
尝试使用:
final Integer[] sum = new Integer[1];
sum[0] = 0;
myList.forEach(i -> {
sum[0] = sum[0] + i;
});
Run Code Online (Sandbox Code Playgroud)
因为 lambda 实际上是一个用于初始化匿名类(并覆盖方法)的语法糖。
这就像你写的一样:
final Integer[] sum = new Integer[1];
sum[0] = 0;
myList.forEach(new Consumer() {
public void accept(Integer element) {
sum[0] = sum[0] + element;
}
});
Run Code Online (Sandbox Code Playgroud)
来自外部作用域并在内部作用域内使用的变量必须是最终变量(在本例中sum)。那只是因为 Java 不支持闭包。因此,外部变量必须标记为final。由于 Integer 本身是不可变的(如果将其声明为最终的,则无法再更改它),因此必须使用包装对象或数组(就像我所做的那样)。
您可以在这里找到更多有用的信息:
| 归档时间: |
|
| 查看次数: |
5552 次 |
| 最近记录: |