The phenomenon of
When writing Lambda expressions, you sometimes refer to variables other than the Lambda expression.
The local variable referenced by a Lambda expression must be final or actually final, that is, local variables cannot be reassigned after being created.
Analysis of the
So why? I have read many articles on the Internet, which are vague, such as:
The variables it can access are only copies of the variables in the external class, so this is to prevent you from thinking you can directly modify the variables in the external class.
I was in a fog until I read this article. Is there a performance problem with using lambda expressions to pass parameters? , which analyzed the principle of Lambda expression syntax sugar, and then I wrote a Test to verify:
import java.util.function.Consumer;
public class LambdaTest {
Object instanceObj = new Object();
private void test(a) {
// For direct references
Object localObj1 = new Object();
// Used to pass parameters
Object localObj2 = newObject(); Consumer consumer = (x) -> { System.out.println(x); System.out.println(localObj1); System.out.println(instanceObj); }; consumer.accept(localObj2); }}Copy the code
After compiling the class, decompile the bytecode:
Javac SRC /LambdaTest. Java javap -p SRC /LambdaTest. Class Compiled from"LambdaTest.java"
public class LambdaTest {
java.lang.Object instanceObj;
public LambdaTest();
private void test(a); private void lambda$test$0(java.lang.Object, java.lang.Object);
}
Copy the code
A direct reference to a local variable in a Lambda expression is essentially an implicit argument. When compiled, the referenced local variable is automatically placed in the argument list (Lambda method has an extra argument). The referenced instance variables do not need to be placed in the parameter list because they can be referenced directly within the method.
So, the reason why the local variables that are directly referenced need final modification is probably related to this implicit parameter passing. Therefore, we need to mention the parameter passing mechanism of Java methods again.
A reference data type in Java consists of two parts: the reference variable and the actual object to which it points. In method parameter passing, you essentially assign the memory address of the actual object to the reference variable ** in the method parameter
So reassigning parameters in a Lambda or reassigning local variables in a method has no effect on the other party.
conclusion
Therefore, in order to avoid confusion and ensure data consistency between local variables and variable copies of Lambda, Java directly syntactic forces that local variables referenced by Lambda expressions cannot be reassigned.
The above analysis is only my personal understanding as a learner, if there is a mistake welcome to leave a message to correct, we make progress together, thank you!
Thank you for reading this article, follow my public account “Yubing Yubing” to receive the latest push, there are also some quality resources I share.