lambda表达式和全局变量

Vic*_*kor 2 java lambda

我刚开始在Java 8中使用lambda表达式.我有点困惑effectively final.

初始化一次的局部变量是effectively final全局变量,我可以改变全局变量的值并在lambda表达式中使用它.那么本地变量应该是什么原因呢effectively final.我找不到任何关于此的文章或javadoc.

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("--------------------------------------");
                        });
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

Firstname: Vicky
Middle: V
Lastname: T
--------------------------------------
Firstname: Thakor
Middle: V
Lastname: T
--------------------------------------
Run Code Online (Sandbox Code Playgroud)

shm*_*sel 6

当您在lambda中引用"全局"变量时,您实际上正在捕获对它的引用this,这实际上是最终的.

请考虑以下代码段(未经测试):

class Main {

    class Box {
        int value;
    }

    void foo() {
        Box box = new Box();
        Runnable r = () -> box.value++;
    }
}
Run Code Online (Sandbox Code Playgroud)

即使你正在改变它box.value,你也是通过box引用来实现的,这实际上是最终的.同样,你的代码相当于

System.out.println("Lastname: " + this.lastname);
Run Code Online (Sandbox Code Playgroud)

意思是你lastname通过this引用访问,这实际上是最终的.