Java – Lambda Expression Variable Capturing with Examples

28 Jul, 2021
Variable defined by the enclosing scope of a lambda expression are accessible within the lambda expression. For example,  a lambda expression can use an instance or static variable defined by its enclosing class. A lambda expression also has access to  (both explicitly and implicitly), which refers to the invoking instance of the lambda expression’s enclosing class. Thus, a lambda expression can obtain or set the value of an intrinsic or static variable and call a method define by its enclosing class.
 Lambda expression in java Using a local variable is as stated.
However, when a lambda expression uses a local variable from its enclosing scope, a special situation is created that is referred to as a variable capture. In this case, a lambda expression may only use local variables that are effectively final. An effectively final variable is one whose value does not change after it is first assigned. There is no need to explicitly declare such a variable as final, although doing so would not be an error.
It is important to understand that a local variable of the enclosing scope cannot be modified by the lambda expression. Doing so would remove its effectively final status, thus rendering it illegal for capture.
There are certain keypoints to be remembered, which are as follows: 
Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final , or a compile-time error occurs where the use is attempted.Any local variable used but not declared in a lambda body must be definitely assigned before the lambda body, or a compile-time error occurs.Similar rules on variable use apply in the body of an inner class . The restriction to effectively final variables prohibits access to dynamically-changing local variables, whose capture would likely introduce concurrency problems. Compared to the final restriction, it reduces the clerical burden on programmers.The restriction to effectively final variables includes standard loop variables, but not enhanced-for loop variables, which are treated as distinct for each iteration of the loop.
Any local variable, formal parameter, or exception parameter used but not declared in a lambda expression must either be declared final or be effectively final , or a compile-time error occurs where the use is attempted.
Any local variable used but not declared in a lambda body must be definitely assigned before the lambda body, or a compile-time error occurs.
Similar rules on variable use apply in the body of an inner class . The restriction to effectively final variables prohibits access to dynamically-changing local variables, whose capture would likely introduce concurrency problems. Compared to the final restriction, it reduces the clerical burden on programmers.
The restriction to effectively final variables includes standard loop variables, but not enhanced-for loop variables, which are treated as distinct for each iteration of the loop.
The following program illustrates the difference between effectively final and mutable local variables:
Example 1
Java
// Java Program Illustrating Difference between// Effectively final and Mutable Local Variables  // Importing reqiored classesimport java.io.*;// An example of capturing a local variable from the// enclosing scope  // Inrterfaceinterface MyFunction {      // Method inside the interface    int func(int n);}  // Main classclass GFG {      // Main driver method    public static void main(String[] args)    {          // Custom local variable that can be captured        int number = 10;          MyFunction myLambda = (n) ->        {              // This use of number is OK It does not modify            // num            int value = number + n;              // However, the following is illegal because it            // attempts to modify the value of number              // number++;            return value;        };          // The following line would also cause an error,        // because it would remove the effectively final        // status from num. number = 9;          System.out.println("GFG!");    }}
GFG!
Output explanation: 
As the comments indicate, number is effectively final and can, therefore, be used inside myLambda. However, if number were to be modified, either inside the lambda or outside of it, number would lose its effective final status. This would cause an error, and the program would not compile. 
Example 2
Java
// Java Program Illustrating Difference between// Effectively final and Mutable Local Variables  // Importing input output classesimport java.io.*;  // Interfaceinterface MyInterface {      // Method inside the interface    void myFunction();}  // Main classclass GFG {      // Custom initialization    int data = 170;      // Main driver method    public static void main(String[] args)    {          // Creating object of this class        // inside the main() method        GFG gfg = new GFG();          // Creating object of interface        // inside the main() method        MyInterface intFace = () ->        {            System.out.println("Data : " + gfg.data);            gfg.data += 500;              System.out.println("Data : " + gfg.data);        };          intFace.myFunction();        gfg.data += 200;          System.out.println("Data : " + gfg.data);    }}
Data : 170
Data : 670
Data : 870
Note: It is important to emphasize that a lambda expression can use and modify an instance variable from its invoking class. It just can’t use a local variable of its enclosing scope unless that variable is effectively final.
java-lambda
Picked
Java
Java
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Object Oriented Programming (OOPs) Concept in Java
How to iterate any Map in Java
Interfaces in Java
HashMap in Java with Examples
ArrayList in Java
Collections in Java
Stream In Java
Multidimensional Arrays in Java
Singleton Class in Java
Set in Java