在访问作为引用的类成员时,lambda表达式是否包含对其封闭实例的引用?

时间:2016-02-16 17:04:11

标签: java lambda reference

我认为描述我的问题的最简单方法是举例:

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,而不是封闭的实例。

顺便说一句,我发现了问题" Does Java8 lambdas maintains a reference to their enclosing instance like anonymous classes?"但是我不清楚什么时候确实将lambda表达式视为"而不是从封闭实例捕获成员&#34 34 ;.另外,the document that is referenced in the accepted answer声明自己已经过时了。

1 个答案:

答案 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();
    });
}    
相关问题