Java Lambda 引用封闭对象:替换为私有静态类?
2022-09-04 20:35:53
从其封闭作用域引用元素的 Java lambda 包含对其封闭对象的引用。一个人为的例子,lambda持有MyClass的引用:
class MyClass {
final String foo = "foo";
public Consumer<String> getFn() {
return bar -> System.out.println(bar + foo);
}
}
如果 lambda 的生存期很长,这是有问题的;然后我们有一个MyClass的参考,它是长期存在的,否则它就会超出范围。在这里,我们可以通过将lambda替换为私有静态类进行优化,以便我们只保留对所需字符串的引用,而不是对整个类的引用:
class MyClass {
private static class PrintConsumer implements Consumer<String> {
String foo;
PrintConsumer(String foo) {
this.foo = foo;
}
@Override
public void accept(String bar) {
System.out.println(bar + foo);
}
}
final String foo = "foo";
public Consumer<String> getFn() {
return new PrintConsumer(foo);
}
}
不幸的是,这是非常冗长的,并且破坏了我们从使用(实际上是最终的)变量中获得的漂亮语法,这些变量来自lambdas中的封闭范围。这在技术上是最佳的吗?在良好的语法和将引用保留到不必要的时间之间是否总是存在权衡?