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 - "Good"使用 Stream API 对每个对象调用方法的方法

JavaFX,TextArea 的通用大小取决于内容,如 "Message Bubble"

java - 如何在 Samsung Galaxy Tab 上停止通话音频并保持通话?

java - 使用 log4j-1.2-api 但找不到 log4j1.x 类

java - 在 gs-uploading-files Spring Boot 示例上将 Java 1.8 lambda 转换为 Java 1.7

kotlin - 如何在 Kotlin 中使用带有 SAM 接口(interface)的函数接收器类型

java - 将 ID 列表传递给 SQL 语句

c# - 在 .NET 语言之间共享类方法

java - 如何在 Javafx 8 中为标签文本添加上标

java - Scala:在 TreeView 中显示 systemDrive