如何在 Java 中正确创建对方法引用的弱引用
How to correctly create a weak reference to method reference in Java
我想将 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));
}
两个问题:
- 当创建方法引用的弱引用时,到底发生了什么?
- (2)和(3)有什么区别?
创建方法引用(在本例中)就像创建任何其他方法引用一样 object。因此,如果我们将其替换为 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
实例立即符合垃圾 collection 的条件,因为没有任何东西对它具有强引用。
- 在示例 3 中,您在
listener
字段中保留对新创建的 Foo
object 的强引用,因此只有当 object 具有listener
字段已收集。
P.s.: 如果 Java 中的方法引用真的是对方法的引用,意味着方法是 first-class objects 在他们自己的权利(就像在 Javascript 中),示例 2 也可以工作,因为每个 object 都会隐式地持有对他们所有方法的引用。
我想将 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));
}
两个问题:
- 当创建方法引用的弱引用时,到底发生了什么?
- (2)和(3)有什么区别?
创建方法引用(在本例中)就像创建任何其他方法引用一样 object。因此,如果我们将其替换为 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
实例立即符合垃圾 collection 的条件,因为没有任何东西对它具有强引用。 - 在示例 3 中,您在
listener
字段中保留对新创建的Foo
object 的强引用,因此只有当 object 具有listener
字段已收集。
P.s.: 如果 Java 中的方法引用真的是对方法的引用,意味着方法是 first-class objects 在他们自己的权利(就像在 Javascript 中),示例 2 也可以工作,因为每个 object 都会隐式地持有对他们所有方法的引用。