为什么编译器拒绝访问 lambda 中的非最终变量
Why does the compiler deny access to non-final variables inside a lambda
我刚看到 ,显然 Java 应该拒绝访问 lambda 表达式主体内的非最终变量。为什么?
编辑:例如,我不明白为什么以下代码有害:
String[] numbers = new String[10]; // put some numerical strings in
BigInteger sum = new BigInteger("0");
numbers.forEach(n -> sum = sum.add(new BigInteger(n)));
Lambda 只是语法糖,它们被编译成 anonymous inner classes
。由于范围的原因,匿名内部 类 不能使用 non-final
局部变量。解释如下:
The local variables of the method live on the stack, and exist only
for the lifetime of the method. You already know that the scope of a
local variable is limited to the method the variable is declared in.
When the method ends, the stack frame is blown away and the variable
is history. But even after the method completes, the inner class
object created within it might still be alive on the heap if, for
example, a reference to it was passed into some other code and then
stored in an instance variable. Because the local variables aren't
guaranteed to be alive as long as the method-local inner class object,
the inner class object can't use them. Unless the local variables are
marked final!
由 Kathy Sierra 和 Bert Bates 提供的 SCJP 6 学习指南提供
我不确定这是否是答案,但在 Java 的文档中,它说明如下:
The restriction to effectively final variables prohibits access to dynamically-changing local variables, whose capture would likely introduce concurrency problems. Compared to the final restriction, it reduces the clerical burden on programmers.
据我了解,当你将lambda表达式传递给方法时,该表达式不应导致并发问题,因为该方法可以被多个线程并发使用,使用非final变量可能会导致并发问题赛车条件。
文档页面,如果您想自己阅读并获取更多信息:http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.2
我刚看到
编辑:例如,我不明白为什么以下代码有害:
String[] numbers = new String[10]; // put some numerical strings in
BigInteger sum = new BigInteger("0");
numbers.forEach(n -> sum = sum.add(new BigInteger(n)));
Lambda 只是语法糖,它们被编译成 anonymous inner classes
。由于范围的原因,匿名内部 类 不能使用 non-final
局部变量。解释如下:
The local variables of the method live on the stack, and exist only for the lifetime of the method. You already know that the scope of a local variable is limited to the method the variable is declared in. When the method ends, the stack frame is blown away and the variable is history. But even after the method completes, the inner class object created within it might still be alive on the heap if, for example, a reference to it was passed into some other code and then stored in an instance variable. Because the local variables aren't guaranteed to be alive as long as the method-local inner class object, the inner class object can't use them. Unless the local variables are marked final!
由 Kathy Sierra 和 Bert Bates 提供的 SCJP 6 学习指南提供
我不确定这是否是答案,但在 Java 的文档中,它说明如下:
The restriction to effectively final variables prohibits access to dynamically-changing local variables, whose capture would likely introduce concurrency problems. Compared to the final restriction, it reduces the clerical burden on programmers.
据我了解,当你将lambda表达式传递给方法时,该表达式不应导致并发问题,因为该方法可以被多个线程并发使用,使用非final变量可能会导致并发问题赛车条件。
文档页面,如果您想自己阅读并获取更多信息:http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.2