【发布时间】:2016-07-11 07:00:08
【问题描述】:
从其封闭范围引用元素的 Java lambda 持有对其封闭对象的引用。一个人为的例子,lambda 持有对 MyClass 的引用:
class MyClass {
final String foo = "foo";
public Consumer<String> getFn() {
return bar -> System.out.println(bar + foo);
}
}
如果 lambda 的生命周期很长,这是有问题的;那么我们有一个长期存在的 MyClass 的引用,否则它会超出范围。在这里,我们可以通过将 lambda 替换为私有静态类来进行优化,这样我们只持有对我们需要的 String 的引用,而不是整个类:
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);
}
}
不幸的是,这是非常冗长的,并且破坏了我们通过在 lambda 中使用(实际上是最终的)变量获得的漂亮语法。这在技术上是最优的吗?在良好的语法和保持 ref 比必要更长的可能性之间总是存在权衡吗?
【问题讨论】:
-
我认为你的假设是不正确的。 lambda 不包含对 MyClass 的引用,仅包含对字符串的引用。
-
@PaulBoddington: That's not correct
-
我的立场是正确的。谢谢 Lukas 并向@Noel 道歉
-
@Ingo:
this被隐式引用
标签: java lambda functional-programming java-8