我已经读到lambda表达式使用的外部变量必须是final或有效的final。 例如,如果我尝试在Supplier主体中修改外部String值,则编译器会按照上面的定义阻止我。 但是,如果我使用外部Pojo(修改其属性-从而更改其内部状态),则它可以正常工作并抵消上面的声明。
怎么了?
package com.quicktutorialz.test;
import java.util.function.Supplier;
public class MainApplication {
public static void main(String[] args){
// MY NON-EFFECTIVELY-FINAL POJO
NamePojo namePojo = new NamePojo();
namePojo.setName("Luisa");
//MY LAMBDA
Supplier<String> supplier = () -> {
namePojo.setName("Alex"); //HOW IS THAT POSSIBLE?!?!
return "Hello " + namePojo.getName();
};
System.out.println(supplier.get());
}
}
class NamePojo {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
答案 0 :(得分:4)
您正在混合一个最终变量和一个不变变量。
最后一个变量意味着它不能被重新分配。示例:
void doSomething() {
int a = 0; // is effectively final
int b = 1; // is not effectively final
b = 2;
}
不可变的变量表示其外部表示形式不会改变。这主要意味着其字段为final
或有效地为final。示例:
class A {
int value;
A(int value) { this.value = value; }
int getValue() { return this.value; }
}
public void doSomething() {
A a = new A(0);
// no way to change a.value
}
public class MainApplication {
public static void main(String[] args){
// MY NON-EFFECTIVELY-FINAL POJO
NamePojo namePojo = new NamePojo(); // namePojo is assigned.
namePojo.setName("Luisa"); // namePojo is changed, but not reassigned.
//MY LAMBDA
Supplier<String> supplier = () -> {
// namePojo is changed, but not reassigned.
namePojo.setName("Alex"); //HOW IS THAT POSSIBLE?!?!
return "Hello " + namePojo.getName();
};
System.out.println(supplier.get());
}
}
变量namePojo
的内容已已更改,但是该变量本身从未重新分配,因为它不是重新分配,实际上是最终的决定。对namePojo
的引用从未在您的代码中更改过,从而使它有效地成为最终。