Variable capture in lambda expression

Lambda expression can access variable of it's enclosing scope. To understand this concept let's take one example.

In example there is functional interface with one abstract method printvalue().

Example :


interface Demo
{
void printValue();
}

now we will create a instance variable of above interface and define functionality of method printValue by using lambda expression.

Example :


class DemoImpl
{
//Instance variable
int a;
//Static variable
static int b;

//Constructor to initialise instance variable
DemoImpl(int x)
{
a=x;
}
// show method to print value of a and b
void show()
{
// Reference of functional interface Demo
Demo d;
// Using lambda expression to define printValue() method
d=()-> {
// Inside lambda expression accessing instance and static variable
System.out.println("Value of a:"+a);
System.out.println("Value of b:"+b);
};
d.printValue();
}
public static void main(String arg[])
{
DemoImpl d=new DemoImpl(12);
d.show();
}
}
/*Output:
Value of a:12;
Value of b:0;
*/

In above code class DemoImple defined. In this class two variable are declared, one is instance variable and another is static variable. Lambda expression has access to "this". It means lambda expression can access invoking object. In above code lambda expression using "this" implicitly. In above code lambda expression printing value of class' instance and static variable both.

Important ! lambda expression has access to it's enclosing class' instance and static variable both.

Local variable access

Lambda expression can also use local variable. Local variable is variable declared in a method. When lambda expression access a local variable this situation is known as Variable Capture .

Lambda expression can access only those local variable whose value won't change in enclosing scope. This feature known as effectively final . It means variable implicitly treated as final variable.

Let's take one example to understand this concept.


interface Demo
{
void printValue();
}
class DemoImpl
{

public static void main(String arg[])
{
//local variable
int a=20;
int b=40;
Demo d;
d=()->{
//lambda exrepssion using local varialbe;
// Now these variable must be effectively final or final
// If we try to change value of a and b now there will be an error.
System.out.println("Value of a:"+a);
System.out.println("Value of b:"+b);
};
d.printValue();
//a=50; Error: a's value can't be changed it's final variable.
}
}
/*Output:
Value of a:20;
Value of b:40;
*/

lambda expression can access local variable of it's enclosing scope. Those variable then become effectively final means implicitly final. Programmer can declare them final as well.

Now if we uncomment the "a=50;" line then compiler will give following error.

Error :

Error DemoImple.java:14: error: local variables referenced from a lambda expression must be final
or effectively final
System.out.println("Value of a:"+a);
^
1 error

Important ! lambda expression can access local variable. These local variable can't be changed after their initialisation.