我想将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/