你问的问题在 Project Lambda 的概述文档上已经解释了,这都属于设计上的取舍。
不能改变外部变量的值是因为线程安全问题。当然这可能不是唯一原因,可能有其他考虑,但文档上清清楚楚说明了:While we relax the syntactic restrictions on captured values, we still prohibit capture of mutable local variables. The reason is that idioms like this:
int sum = 0;
list.forEach(e -> { sum += e.size(); }); // ERROR
are fundamentally serial; it is quite difficult to write lambda bodies like this that do not have race conditions. Unless we are willing to enforce -- preferably at compile time -- that such a function cannot escape its capturing thread, this feature may well cause more trouble than it solves. Lambda expressions close over values, not variables.
当然你可以通过一个包装类,或者一个大小为 1 的数组轻松绕过这个限制,但是在这时就应该由你自己保证线程的安全问题。
不能遮蔽变量也有说明:Lambda expressions are much simpler: they do not inherit any names from a supertype, nor do they introduce a new level of scoping. Instead, they are lexically scoped, meaning names in the body are interpreted just as they are in the enclosing environment (with the addition of new names for the lambda expression's formal parameters). As a natural extension, thethiskeyword and references to its members have the same meaning as they would immediately outside the lambda expression.
Consistent with the lexical-scoping approach, and following the pattern set by other local parameterized constructs likeforloops andcatchclauses, the parameters of a lambda expression must not shadow any local variables in the enclosing context.
这里说的很清楚了,为了保持简单性,词法范围内 lambda 和块的是一样的,不允许对局部变量进行遮蔽。