Why can't Lambda expressions (anonymous classes) access non-final local variables?
Because instance variables are stored in the heap, and local variables are allocated on the stack, Lambda expressions (anonymous classes) will be executed in another thread. If you want to directly access a local variable in the thread, the local variable may have been destroyed when the thread is executed, and the local variable of the final type is actually a copy of the local variable in the Lambda expression (anonymous class).
What variables can be captured by Lambda in Java 8?
(1). There are no restrictions on capturing instances or static variables (it can be considered to refer to the first two through the final type of local variable this);
(2). The captured local variables must be explicitly declared as final or actual final type.
Recall that before Java 8, if you want to access a local variable in an anonymous class, that local variable must be explicitly declared as final.
Java 7 requires that this local variable must be of final type, otherwise it cannot be referenced in anonymous classes.
The same code above can be compiled in Java 8. Doesn't Java 8 need version to be final? Not really
1 2 3 4 5 6 7 8 |
|
That is, under Java 8, even if a local variable is not declared as a final type, once it is accessed in an anonymous class, it is strongly typed with a final attribute, so the version cannot be assigned again later.
The previous demonstration is an anonymous class, it is the same thing to change to Lambda expression in Java 8
1 2 3 |
|
Therefore, although Java 8 Lambda expressions have no hard and fast rules to be declared as final when accessing local variables, they are essentially the same as Java 7.
In short, if a local variable is to be accessed in an anonymous class in Java 7/8 or a Lambda expression in Java 8, then the local variable must be final.
Note that it is not the local variable that becomes final when Lambda starts to access it. This is a requirement of the compiler, for example
1 2 3 |
|
In other words, if the local variable accessed in an anonymous class or Lambda expression is not a final type, the compiler automatically adds a final modifier.