Closures in Lambda expressions- Functional Programming in JAVA 8- Part 7

Before reading this post kindly go from part 1 of this post to understand lambda expression.

Understanding JAVA 8 Lambda Expression- Functional Programming in JAVA 8- Part 1

Closures is a very important concept when you are looking at Functional programming, i.e. you are able to pass functions from one place to another in the code as values.
We have already seen closures in JAVA 7(kind of). Anonymous inner class concept of JAVA 7 is very close to closures(its kind of behaves as closures).

public class ClosuresExample {

	public static void main(String[] args) {
		int a=10;
		doProcess(a, new Process() {
			@Override
			public void process(int i) {
				System.out.println(i);
			}
		});
	}
	
	public static void doProcess(int i, Process p){
		p.process(i);
	}
}

interface Process{
	void process(int i);
}

Output- 10

Fairly simple, we have have an anonymous inner class which has the implementation of Process interface which prints whatever is passed to variable i.
Now suppose, in your anonymous inner class you want to print addition of i variable value with say b variable value. Something like below:-

public class ClosuresExample {

	public static void main(String[] args) {
		int a=10;
		int b=20;
		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);
}

Output- 20

Again, seems fairly simple, just addition of one variable value with another. When compiler reaches our anonymous inner class implementation it sees variable b and since it’s not inside anonymous inner class it goes out and finds variable b.
But doesn’t it look strange that though our inner class implementation is in the main method but it’s actually passed to the doProcess() method and it’s inside the doProcess() method that our anonymous inner class implementation got executed. So in our doProcess() method when we do p.process(i);, is there variable b in the scope? No it doesn’t seems, as in the doProcess() method there is no variable b.
So, actually JAVA compiler is keeping track of the variable b. Here variable b has the value 20, so JAVA compiler knows what value to use for variable b whenever our anonymous inner class implementation gets executed.

Now what if you want to change the value of variable b to something else. No, you can’t you will get an error “Local variable b defined in an enclosing scope must be final or effectively final”.
Before JAVA 8 you had to declare variables like b(those variables that are used by anonymous inner class but are declared outside of it) as final. That is you don’t intend to change this variable. From JAVA 8, variables like b are effectively final(implicitly final), it’s not necessary to mark the variable as final, JAVA compiler assumes it to be final.
We cannot change the variable b, however we can read the variable inside anonymous inner class implementation and wherever our implementation goes the value of the variable goes around. The variable doesn’t gets passed around it’s the value which is frozen gets passed around.
So, this is the concept that is similar to closures that we have in functional programming. Now let’s replace above anonymous inner class implementation with lambda expression.

public class ClosuresExample {

	public static void main(String[] args) {
		int a=10;
		int b=20;
                doProcess(a, i->System.out.println(i+b));
	}
	
	public static void doProcess(int i, Process p){
		p.process(i);
	}
}

interface Process{
	void process(int i);
}

Output- 20

Our lambda expression is getting passed to doProcess() method and it’s executed here. And when our lambda expression gets executed inside doProcess() method, you must know that the value of variable b is coming from the concept of closures.

Whenever there is a lambda expression and it’s using a variable in it’s scope, JAVA compiler freezes the value of the variable. Wherever the lambda expression goes, the value of variable goes along with it. And, compiler expects these kinds of variables to be effectively final.

Leave a Reply

Your email address will not be published. Required fields are marked *