In a lambda, local variables need to be final, but instance variables don't. Why so?
Forcing the variable to be final avoids giving the impression that incrementing start inside the lambda could actually modify the start method parameter.
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.
Like methods, local variables and parameters need not to be declared final.
Local variables from outer scope can be captured inside Lambda in 2 modes i.e.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With