java - 如何在Java中正确创建对方法引用的弱引用

标签 java lambda javafx weak-references

我想将JavaFX ListChangeListener注册到ObservableList。但是我注意到,在某些情况下,不会调用Listener。

(1)如果Listener是方法引用,则一切正常:

// using a direct method reference:
private final ListChangeListener<String> listener = this::listDidChange;

/* ... */
public void init() {
    list.addListener(listener);
}


(2)但是,如果侦听器是对该方法的弱引用,则不会调用该侦听器:

// using a weak method reference:
private final ListChangeListener<String> listener = new WeakListChangeListener<String>(this::listDidChange);

/* ... */
public void init() {
    list.addListener(listener);
}


(3)现在,真正有趣的部分是,即使它应该与前面的示例相同,它仍然可以正常工作:

// direct method reference wrapped into a weak ref later:
private final ListChangeListener<String> listener = this::listDidChange;

/* ... */
public void init() {
    list.addListener(new WeakListChangeListener<String>(listener));
}


两个问题:


创建对方法ref的弱引用时,会发生什么情况?
(2)和(3)有什么区别?

最佳答案

创建方法引用(在这种情况下)就像创建任何其他对象一样。因此,如果我们将其替换为new表达式,示例2将变为:

private final ListChangeListener<String> listener = new WeakListChangeListener<String>(new Foo());

public void init() {
    list.addListener(listener);
}


而示例3是:

// direct method reference wrapped into a weak ref later:
private final ListChangeListener<String> listener = new Foo();

public void init() {
    list.addListener(new WeakListChangeListener<String>(listener));
}


现在区别变得非常明显:


在示例2中,新创建的Foo实例可立即进行垃圾回收,因为没有什么东西对其有很强的引用。
在示例3中,您在Foo字段中强烈引用了新创建的listener对象,因此只有在收集了带有listener字段的对象时才会收集该对象。


附言:如果Java中的方法引用确实是对方法的引用,则意味着方法本身就是一流的对象(如Javascript),示例2也会起作用,因为每个对象都隐式持有对其所有方法的引用。

关于java - 如何在Java中正确创建对方法引用的弱引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31082168/

相关文章:

java - 为什么我不能在 Java 8 lambda 表达式中引发异常?

java - 如果小于视口(viewport),则扩展滚动 Pane 的内容

java - 在一个列表中查找匹配项并将其删除

java - 将嵌套 xml 元素映射到单个 Java 对象

java - Java中无法分配LinkedList头节点以供将来引用

c# - 如何在 Nest ElasticSearch 客户端中编写日期范围查询?

python - 如何在for循环中使用lambda?

mysql - com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException : Unknown column 'poi' in 'where clause'

checkbox - 我的CheckBox中的下划线在哪里?

java - Java中如何将数字四舍五入到小数点后n位