Lambda 表达式没有有效的 final 变量
Lambda Expression works with no effectively final variable
我读到 lambda 表达式使用的外部变量必须是最终的或实际上是最终的。
例如,如果我尝试修改 Supplier 主体中的外部字符串值,编译器会阻止我,正如上面的定义。
但是如果我使用外部 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;
}
}
变量(实际上)是最终的,它的字段不是。
您正在混合最终变量和不可变变量。
final 变量意味着它不能被重新赋值。示例:
void doSomething() {
int a = 0; // is effectively final
int b = 1; // is not effectively final
b = 2;
}
不可变变量意味着它的外部表示不会改变。这主要意味着它的字段是 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
的引用在您的代码中从未更改,使其 最终有效 。
我读到 lambda 表达式使用的外部变量必须是最终的或实际上是最终的。 例如,如果我尝试修改 Supplier 主体中的外部字符串值,编译器会阻止我,正如上面的定义。 但是如果我使用外部 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;
}
}
变量(实际上)是最终的,它的字段不是。
您正在混合最终变量和不可变变量。
final 变量意味着它不能被重新赋值。示例:
void doSomething() {
int a = 0; // is effectively final
int b = 1; // is not effectively final
b = 2;
}
不可变变量意味着它的外部表示不会改变。这主要意味着它的字段是 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
的引用在您的代码中从未更改,使其 最终有效 。