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.