Why use final in lambda expressions

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

String version = "1.8";

foo(new Supplier() {

  @Override

  public String get() {

   return version;

  }

});

version = "1.7"//在 Java 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

String version = "1.8";

foo(() -> version); //对局部变量 version 的访问让 version 变成 final 了

version = "1.7";  //有了这行就编译不过了

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

String version = "1.8";

version = "1.7";      //注释掉这行或下行中另一行才能编译通过

foo(() -> version );  //这行让编译器决定给 version 加上 final 属性

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.

 

 

 

Guess you like

Origin blog.csdn.net/johnt25/article/details/86176151