Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does variables in lambdas have to be final or effectively final? [duplicate]

When I am writing this code I am getting a compile time error which says: 'Variables in lambdas must be final or effectively final'.

Now, I get this that removing the i from the line :

futureLists.add(executorService.submit( () -> "Hello world" + i));

solves the issue.

But I want to know that why does such a requirement exist?

As per the JLS, all it says is :

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.

But it does not state, why such a requirement exist. But why did Java engineers enforce such a requirement for lambdas?

public class test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
         ExecutorService executorService = Executors.newFixedThreadPool(10);

         List<Future<String>> futureLists = new ArrayList<>();

         for (int i = 0; i < 20; i++) {
             futureLists.add(executorService.submit( () -> "Hello world" + i));
             }

         for (Future<String> itr:futureLists) {
             System.out.println(itr.get());
            }
       }
   }
like image 576
QuackDuck Avatar asked May 21 '18 21:05

QuackDuck


1 Answers

It is related to multi-thread programming.

Local variables in Java have until now been immune to race conditions and visibility problems because they are accessible only to the thread executing the method in which they are declared. But a lambda can be passed from the thread that created it to a different thread, and that immunity would therefore be lost if the lambda, evaluated by the second thread, were given the ability to mutate local variables. - Source

like image 193
snr Avatar answered Nov 15 '22 19:11

snr