V
V
Volokoron2020-12-05 14:41:59
Java
Volokoron, 2020-12-05 14:41:59

Lambda scope/closure in Java?

public void m() {
        Human human1 = new Human(25, "Sam");
        Human human2 = new Human(25, "Max");
        Runnable r1 = () -> {
            System.out.println(human1.age + "-" + human2.age); //Почему не происходит ошибка?!
        };
        human1.age = 100;
        human2.age = 100;
        
        int var  = human1.age;
        Runnable r2 = () -> {
            System.out.println(var);
             //Ошибка компилятора
            //Variable (var) used in lambda expression should be final or effectively final
        };
        var = 12;
}

Good day!
Why doesn't the effectively final/final error occur in the first case?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry Roo, 2020-12-05
@Volokoron

The point is that human1 and human2 are indeed EffectivelyFinal.
These variables contain a reference to an object. This link does not change.
The var variable is obviously not EffectivelyFinal.
Try assigning a new object to human1 and you will see the same compiler warning.
Quote from The Modern Java Language. Lambda Expressions, Threads, and Functional Programming”:


You may have heard the term “closure” (don’t confuse it with the Clojure programming language) and are wondering if lambda expressions fit the definition. In a more formal language, a closure is an instance of a function with the ability to access variables that are non-local with respect to this function without any restrictions. For example, a closure can be passed as an argument to another function. It can also access variables declared outside its scope and change their values. Java 8 lambda expressions and anonymous classes are similar to closures: they can be passed as arguments to methods, and they can access variables outside of their scope. But they have a limitation: they cannot modify the contents of the local variables of the method in which they are described. These variables are in fact immutable (final).As explained earlier, this limitation is due to the fact that local variables reside on the stack and are implicitly constrained by their thread of execution. Allowing the capture of mutable local variables opens up new thread-unsafe and therefore undesirable features (instance variables are legal in this sense because they are stored on a heap shared by different threads of execution).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question