Reputation: 403
Was going through a closure example for the first time , but I'm having a hard time wrapping my head around the control flow.
public class TestLambdaClosure {
public static void main(String[] args) {
int a= 10;
int b=20;
//doProcess(a, i-> System.out.println(i+b));
doProcess(a, new Process() {
@Override
public void process(int i) {
System.out.println(i+b);
}
});
}
public static void doProcess(int i, Process p) {
p.process(i);
}
interface Process{
void process(int i);
}
}
How does 'b' get in the scope when p.process(i) is called? Also, how does the control flow work here internally?
Upvotes: 1
Views: 99
Reputation: 10882
Closures allow you to model behavior by encapsulating both code and context into a single construct.
The key concept is that your function code (lambda) can refer to not only its own variables, but also to everything outside visible for the code, variables a
and b
in your case.
In Java, closures can refer only to final or effectively final variables. It means, the reference of the variable cannot change and the closure sees only the actual immutable state (the value is actually not immutable, final means the variable cannot be reassigned). In the theory, this is not necessary. For example in JavaScript, you can write such code:
function newCounter() {
let count = 0;
return function() { return ++count; };
}
const nc = newCounter();
console.log(nc()); // 1
console.log(nc()); // 2
console.log(nc()); // 3
Here, the inner function of newCounter
still has access to count
(its context) and can modify it (the variable is mutable).
Notice, that variable counter
is not accessible to any other parts of your code outside of the closure.
Upvotes: 2
Reputation: 1249
Closures let you access variables in their outer scopes. Outer scope variable in this case (b) is declared as what java community now it calls effectively final, meaning that it's value isn't changed since initialization ( int b = 20 ) in order to be accessible.
Bare in mind that variables need to be declared as final or effectively final in order for this to work as closures.
Now regarding your code, this code declares doProcess(...) method that returns a method for partial performing of the doProcess(...) method.
The process(...) method accesses b in the outer scope of the doProcess(...) method, which is declared as effectively final.
Upvotes: 2