Use instead of variable N
field of some object. Java does not allow writing to variables accessible from the closure, since closure is done by value, not by reference.
This can not be done
http://ideone.com/4d8Seg
import java.util.*; import java.lang.*; import java.io.*; import java.util.function.*; class Ideone { public static void main (String[] args) throws java.lang.Exception { int a = 9; Consumer<Integer> f = (Integer b) -> { System.out.println(a + b); // a = 3; // ERROR }; f.accept(10); // a = 3; // ERROR } }
But like this, you can
http://ideone.com/CkyIuK
import java.util.*; import java.lang.*; import java.io.*; import java.util.function.*; class Ideone { static class Wrapper { public Integer a; } public static void main (String[] args) throws java.lang.Exception { Wrapper w = new Wrapper(); wa = 9; Consumer<Integer> f = (Integer b) -> { System.out.println(wa + b); wa = 7; // Allowed }; f.accept(10); f.accept(10); wa = 3; // Allowed f.accept(10); } }
Hmm ... Why can't the last assignment in the first example be made? .. 0_o
Because the closure in Java is done by value. The copy of the variable a
falls into the function f
scope. Naturally, changing the variable inside or outside f
will not affect the second copy. Therefore, we decided that it is impossible to change the variable anywhere. That is, the variable must be final
, but it is allowed not to write, as long as it actually is immutable.
By the way, in C # this is solved by automatically placing the lockable variables in an intermediate object. Accordingly, any change in the fields of this object is visible in both places.
In C ++, you need to explicitly indicate whether the lambda will receive a value or a link. This approach is not applicable in Java and Sharpe, since the function may exist longer than the variable in the stack - in this case, the reference to the variable will become incorrect and this is not verifiable. In the pros, of course, the responsibility for such an action on the programmer.