我刚开始在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("--------------------------------------");
});
}
}
输出
Firstname: Vicky
Middle: V
Lastname: T
--------------------------------------
Firstname: Thakor
Middle: V
Lastname: T
--------------------------------------
答案 0 :(得分:6)
当您在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);
意味着您通过lastname
引用访问this
,这实际上是最终的。