java - lambda 表达式和全局变量

标签 java lambda

我刚刚开始研究 Java 8 中的 lambda 表达式。我对有效的最终有点困惑。

初始化一次的局部变量实际上是final,但是全局变量呢,我可以更改全局变量的值并在lambda表达式中使用它。那么局部变量应该是有效的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("--------------------------------------");
                        });
    }
}

输出

Firstname: Vicky
Middle: V
Lastname: T
--------------------------------------
Firstname: Thakor
Middle: V
Lastname: T
--------------------------------------

最佳答案

当您在 lambda 中引用“全局”变量时,您实际上捕获了对 this 的引用,这实际上是最终的。

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

class Main {

    class Box {
        int value;
    }

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

即使您要更改 box.value,您也是通过 box 引用来完成的,这实际上是最终的。同样,您的代码相当于

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

这意味着您正在通过 this 引用访问 lastname,该引用实际上是最终的。

关于java - lambda 表达式和全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30728716/

相关文章:

java - 合并或更新持久化对象

java - 了解 Java 内部类中的作用域

java - 在 spring boot 测试中使用 wiremock 随机端口设置属性

python - 用常量 x 映射 lambda x,y

lambda - Kotlin 扩展 lambda 与常规 lambda

c++ - 将不可复制的闭包对象传递给 std::function 参数

java - ViewPager、FragmentStatePagerAdapter、ListFragment单独列出每个Fragment的数据

Java 元素图标 SWT ECLIPSE

C++11 lambda捕获 `this`并按值捕获局部变量

java - Android 实例化和重写模式