Seb*_*n S 2 java lambda javafx weak-references
我想一个JavaFX注册ListChangeListener一个ObservableList.但是我注意到,在某些情况下,监听器没有被调用.
(1)如果监听器是方法参考,一切都有效:
// using a direct method reference:
private final ListChangeListener<String> listener = this::listDidChange;
/* ... */
public void init() {
list.addListener(listener);
}
Run Code Online (Sandbox Code Playgroud)
(2)但是如果Listener是同一方法的弱引用,则不调用监听器:
// using a weak method reference:
private final ListChangeListener<String> listener = new WeakListChangeListener<String>(this::listDidChange);
/* ... */
public void init() {
list.addListener(listener);
}
Run Code Online (Sandbox Code Playgroud)
(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));
}
Run Code Online (Sandbox Code Playgroud)
两个问题:
创建方法引用(在本例中)就像创建任何其他对象一样.因此,如果我们用new表达式替换它,示例2变为:
private final ListChangeListener<String> listener = new WeakListChangeListener<String>(new Foo());
public void init() {
list.addListener(listener);
}
Run Code Online (Sandbox Code Playgroud)
而示例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));
}
Run Code Online (Sandbox Code Playgroud)
现在差异变得相当明显:
Foo立即有资格进行垃圾收集,因为没有任何强大的引用.Foo,您对listener字段中新创建的对象保持强引用,因此仅在收集具有listener字段的对象时才会收集它.Ps:如果Java中的方法引用确实是对方法的引用,意味着方法本身就是第一类对象(比如在Javascript中),那么示例2也会起作用,因为每个对象都会隐式地保存对所有方法的引用.
| 归档时间: |
|
| 查看次数: |
891 次 |
| 最近记录: |