我认为描述我的问题的最简单方法是举例:
class Enclosing {
private ObjectOfInterest o = new ObjectOfInterest();
public void registerEventListener() {
EventEmitter.onEvent(() -> {
// Need to access 'o' here, while 'this' is not important.
o.yeeha();
});
}
}
lambda表达式是否包含对其Enclosing
实例的隐式引用?如果是这样,我怎样才能避免这种情况以避免内存泄漏?我需要在事件监听器中访问o
,而不是封闭的实例。
答案 0 :(得分:4)
您的lambda必须维护对Enclosing
的引用,因为可以在lambda创建和执行之间更改字段的值。如果您将下一个代码添加到registerEventListener
的末尾:
o = null;
然后您会期望您的事件监听器失败并显示NullPointerException
。因此,它必须保留对this
的引用。
另外我应该提一下,即使字段为this
,它也必须保持对final
的引用,因为它的值仍然可以在反射的帮助下改变。
但是,如果您只需要使用在创建lambda时设置的值,那么您可以创建一个局部变量并在lambda中使用它:
public void registerEventListener() {
final ObjectOfInterest currentO = this.o;
EventEmitter.onEvent(() -> {
currentO.yeeha();
});
}