4

I just started working around lambda expression in Java 8. I'm bit confused about effectively final.

Local variable initialized once is effectively final but what about global variable, I can change value of global variable and use it in lambda expression. So what is the reason behind local variable should be effectively final. I couldn't find any articles or on javadoc about this.

import java.util.ArrayList;
import java.util.List;

public class Main {

    private String lastname = "Thakor";

    public static void main(String[] args) {
        Main objMain = new Main();
        objMain.test();
    }

    public void test(){
        List<String> listStrings = new ArrayList<String>();
        listStrings.add("Vicky");
        listStrings.add("Thakor");

        String middlename = "V";
        //Local variable middlename defined in an enclosing scope must be final or effectively final
        /* middlename = "T";*/ 

        /**
         * In case of global variable, why lambda expression not throwing error...
         * Local variable middlename defined in an enclosing scope must be final or effectively final
         */
        lastname = "T"; 

        listStrings.stream()
                        .forEach(firstname ->{
                            System.out.println("Firstname: " + firstname);
                            System.out.println("Middle: " + middlename);
                            System.out.println("Lastname: " + lastname);
                            System.out.println("--------------------------------------");
                        });
    }
}

Output

Firstname: Vicky
Middle: V
Lastname: T
--------------------------------------
Firstname: Thakor
Middle: V
Lastname: T
--------------------------------------
5
  • possible duplicate of Difference between final and effectively final Commented Jun 9, 2015 at 9:56
  • 2
    @JordiCastilla, not really Commented Jun 9, 2015 at 9:57
  • @JordiCastilla I know the difference but I'm asking about global variable. Commented Jun 9, 2015 at 9:58
  • 1
    There are no global variables in Java. The instance variable is not in the (immediately) enclosing scope, it's just being used there. It's being accessed through a reference to the object itself. Commented Jun 9, 2015 at 9:59
  • @Vicky I can't recall the exact reason behind requiring local variables to be effectively final but I assume it has got something to do with threads using the local variables from the stack. Commented Jun 9, 2015 at 10:00

1 Answer 1

7

When you reference a "global" variable in a lambda, you're really capturing a reference to this, which is effectively final.

Consider the following snippet (untested):

class Main {

    class Box {
        int value;
    }

    void foo() {
        Box box = new Box();
        Runnable r = () -> box.value++;
    }
}

Even though you're changing the box.value, you're doing it through the box reference, which is effectively final. Similarly, you code is equivalent to

System.out.println("Lastname: " + this.lastname);

meaning you're accessing lastname through the this reference, which is effectively final.

Sign up to request clarification or add additional context in comments.

5 Comments

Sorry I'm not getting your answer. I'm still confused.
@VickyThakor, which part are you stuck on? Do you understand the example snippet?
accessing lastname through the this reference Why it refer the variable as effectively final when accessing through reference? What makes it different from local variables? Frankly I don't understand the logic behind it. Can you explain it how java treat it from compiler level to run time.
@VickyThakor, I recently saw it put this way: Java closures close over values, not variables. box is a value. this is a value. final variables are effectively values. Allowing mutable variables to be referenced in a lambda would imply that the lambda captures the variable itself, not just its value.
Global variable you can update, but cannot do for Final declared variable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.