Why must the local variable FI and nal used in lambda be fi nal or valid?

Posted by putraaridana on Tue, 23 Nov 2021 13:42:44 +0100

Direct answer

JLS gives us some hints that restricting access to dynamic local variables by valid final variables may introduce concurrency problems. But what English is this?

Simply put: java is designed to prevent the modification of data from being out of sync, that is, to prevent the outer local variables you use inside the lambda from being modified by the outer code, but inside the lambda it cannot be synchronized.

With the property of the final property, it cannot be modified after initialization, and the property can be understood to be read and changed.

Java prompt must have final:

public static void main(String[] args) {         int[] nums = new int[]{1,2,4};         int num = 1;              //External modification          Num--;          nums = new int[]{1};          Thread thread= new Thread((()->{              nums[0] = 0;              Int result = num-1;         });     } Replication Error Replication Successful

The essence of lambda functions

If you haven't used a lambda expression, you should have used an anonymous function as well. The essence of lambda expression is an anonymous function. More reasonably, an instance of a functional interface implementation.

Is the implementation of an interface, so how are external variables passed?

Conditionally, it is through the constructor

Why not a common method and constructor? Because Ramda is about explaining parameters, but not arbitrary, its parameter list depends on the constructor of the interface.

When the lambda expression is instantiated, the compiler creates a new class file (think about whether you exposed the Main$1.class file after the project was compiled) , which is the byte code file of the class instantiated by lambda, in which the compiler creates a constructor whose arguments include the outer local variables you want to use, so the outer local variables are used internally by the lambda's constructor instance.

Value and Reference Passes

You pass arguments through a constructor, which is also the method.

If this variable is of the basic type, it may be a variable transfer, and your variable-level code has been modified, then it may also be on this variable within the lambda, so you can find the external problem.

It's also official to avoid misunderstanding, it's actually a copy, not the original value

Anonymous functions will cause errors inside lambda functions as soon as the outside of me changes:

public static void main(String[] args) {         int num = 1;         //External modification          Num--;          Thread thread= new Thread((()->{              int result = num - 1;    // Report errors         });     } Replication Error Replication Successful

In the case of reference passing, this is not really a problem, because finalkey only maintains the address of the reference, not the attribute values inside the referenced object, which is possible:

public static void main(String[] args) {         int[] nums = new int[]{1,2,4};         //External modification          nums[0] = 0;     //     nums = new int[]{1}; this will cause an error and the nums address will change          Thread thread= new Thread((()->{              nums[0] = 1;         });     } Replication Error Replication Successful

However, if the nums address changes, an error will still occur and a link will be passed to the surface value.

lambda is a declaration, not an execution

Whether it's a lambda or an anonymous internal class, when you write a lambda expression, you don't directly execute the lambda expression. A lambda is just a kind of lambda. You declare an int x just like a variable. A lambda expression may be called after many lines of code before it is executed

Continue with the example above:

public static void main(String[] args) {         int num = 1;         Thread thread= new Thread(()->{    //3              int result = num - 1;    // Report errors         });          thread.start();    // 6          Num --;    // 7     } Replication Error Replication Successful

Line 3 here is a lambda declaration and cannot be executed immediately.

Line 6 starts the thread to execute this lambda

Perhaps line 7 was modified to execute first, to zero the value in your lambda and then 1 the value in your lambda, which caused the data to be out of sync, which also explains the opening statement that variables may introduce concurrency problems.

  Scan VX for Java, Front End, Testing, python, etc.

Topics: Java Spring Boot Back-end