Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambdas: local variables need final, instance variables don't

In a lambda, local variables need to be final, but instance variables don't. Why so?

like image 532
Gerard Avatar asked Jul 31 '14 09:07

Gerard


People also ask

Why do variables in lambda need to be final?

Forcing the variable to be final avoids giving the impression that incrementing start inside the lambda could actually modify the start method parameter.

Can we use Non final variable in lambda?

A non-final local variable or method parameter whose value is never changed after initialization is known as effectively final. It's very useful in the context of the lambda expression. If you remember, prior to Java 8, we cannot use a non-final local variable in an anonymous class.

Should local variables be final?

Like methods, local variables and parameters need not to be declared final.

Can lambda function access local variables?

Local variables from outer scope can be captured inside Lambda in 2 modes i.e.


2 Answers

The fundamental difference between a field and a local variable is that the local variable is copied when JVM creates a lambda instance. On the other hand, fields can be changed freely, because the changes to them are propagated to the outside class instance as well (their scope is the whole outside class, as Boris pointed out below).

The easiest way of thinking about anonymous classes, closures and labmdas is from the variable scope perspective; imagine a copy constructor added for all local variables you pass to a closure.

like image 195
Adam Adamaszek Avatar answered Oct 13 '22 14:10

Adam Adamaszek


In document of project lambda : State of the Lambda v4

Under Section 7. Variable capture, It is mentioned that....

It is our intent to prohibit capture of mutable local variables. The reason is that idioms like this:

int sum = 0; list.forEach(e -> { sum += e.size(); }); 

are fundamentally serial; it is quite difficult to write lambda bodies like this that do not have race conditions. Unless we are willing to enforce—preferably at compile time—that such a function cannot escape its capturing thread, this feature may well cause more trouble than it solves.

Edit :

Another thing to note here is, local variables are passed in constructor of inner class when you access them inside your inner class, and this won't work with non final variable because value of non-final variables can be changed after construction.

While in case of instance variable, compiler passes reference of class and class' reference will be used to access instance variable. So it is not required in case of instance variables.

PS : It is worth mentioning that, anonymous classes can access only final local variables (in JAVA SE 7), while in Java SE 8 you can access effectively final variables also inside lambda as well as inner classes.

like image 41
Not a bug Avatar answered Oct 13 '22 16:10

Not a bug