为什么java8的foreach循环中的变量应该是final?

sch*_*der 28 lambda java-8

我在Java 7循环和Java 8 forEach循环中迭代数组列表.Java 8循环希望循环内的变量是最终的.例如,

List<String> testList = Arrays.asList( "apple", "banana", "cat", "dog" );
int count = 0;

testList.forEach(test -> {
  count++; // Compilation error: Local variable count defined in an enclosing scope must be final or effectively final
});

for (String test : testList) {
  count++; // Code runs fine
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么会这样吗?这是Java 8的缺点吗?

Tag*_*eev 49

Java内存模型具有非常重要的属性:它保证局部变量和方法参数永远不会被另一个线程写入.这为多线程编程增加了很多安全性.但是,当您创建lambda(或匿名类)时,没有人知道它将如何使用.它可以传递给另一个线程执行(例如,如果你使用parallelStream().forEach(...)).是否可以修改将违反重要属性的局部变量.不是Java语言开发人员会牺牲的东西.

通常当你使用lambdas时,你试图以功能方式编程.但在函数式编程中,可变变量被认为是不好的做法:最好只为每个变量赋值一次.因此,尝试修改局部变量实际上是闻起来的.使用各种流减少方法而不是forEach产生良好的功能代码.