问题
I just saw this question, and apparently it's obvious that Java should deny access to non-final variables inside the body of a lambda expression. Why?
Edit: for example, I don't see why the following code is harmful:
String[] numbers = new String[10]; // put some numerical strings in
BigInteger sum = new BigInteger("0");
numbers.forEach(n -> sum = sum.add(new BigInteger(n)));
回答1:
Lambdas are just syntactic sugar and they get compiled into anonymous inner classes
. Anonymous inner classes can't use non-final
local variables because of their scope. Here's the explanation:
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!
Courtesy: SCJP 6 Study guide by Kathy Sierra and Bert Bates
回答2:
I'm not sure if this is the answer, but in Java's documentation, it states the following:
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.
What I understand from this is that when you pass a lambda expression to a method, the expression should not cause concurrency problems, since this method can be used concurrently by multiple threads, and using non-final variables would likely cause racing conditions.
The documentation page if you want to read it for yourself and get further info: http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.2
来源:https://stackoverflow.com/questions/42563967/why-does-the-compiler-deny-access-to-non-final-variables-inside-a-lambda