当使用lambda表达式向某些JavaFX属性添加侦听器时,我们可能会遇到一个经典的陷阱,我们将面临内存泄漏或我们设置的侦听器不会被调用的位置:
void init() {
someProperty.addListener(this::onChanged); // might create a memory leak
someProperty.addListener(new WeakChangeListener<String>(this::onChanged)); // no memory leak, but the listener won't be called
}
以下解决方案有效:
private final ChangeListener<String> changeListener = this::onChanged;
void init() {
someProperty.addListener(new WeakChangeListener<>(changeListener)); // OK, but requires an extra field + WeakChangeListener
}
是否有其他解决方案来设置一个没有太多样板代码的lambda的侦听器?
修改 存在另一个令人困惑的情况,虽然与Lambda表达式无关但仍与JavaFX使用弱引用有关,其中以下代码不起作用:
private final ObservableList<Person> persons = FXCollections.observableArrayList();
public ObservableList<Person> getPersons() {
return FXCollections.unmodifiableObservableList(persons); // a client invoking getPersons().addListener(someListener) won't be notified
}
但是这段代码可以工作(虽然有一些额外的样板代码):
private final ObservableList<Person> persons = FXCollections.observableArrayList();
private final ObservableList<Person> immutableList = FXCollections.unmodifiableObservableList(persons); // needed for our clients to be notified
@SuppressWarnings("ReturnOfCollectionOrArrayField") // needed to avoid a warning
public ObservableList<Person> getPersons() {
return this.immutableList;
}
我在这里使用“令人困惑”这个词,因为: