Java 8 为什么更改侦听器的行为<;T>;根据T参数的不同而不同
考虑以下计划:Java 8 为什么更改侦听器的行为<;T>;根据T参数的不同而不同,java-8,javafx-8,Java 8,Javafx 8,考虑以下计划: import javafx.beans.property.ListProperty; import javafx.beans.property.SimpleListProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.collections.FXCollections; /** * * @a
import javafx.beans.property.ListProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
/**
*
* @author kachna
*/
public class ListPropertyTest {
public static void main(String[] args) {
StringProperty p = new SimpleStringProperty();
p.addListener((obs, old, nw) -> {
System.out.println("String Property; oldString: " + old + ", newString: " + nw);
});
p.set("1");
ListProperty<String> listProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
listProperty.addListener((obs, old, nw) -> {
System.out.println("ListProperty; oldList: " + old + ", newList: " + nw);
});
listProperty.addAll("1", "2", "3");
}
}
如您所见,旧值为:
null
当T
是字符串时
T
为
可观察列表
这是一个错误:
ListProperty
当包装列表的内容更改时,不应该触发更改的事件:它应该只触发列表更改的事件。换句话说,您应该只能检测来自的更改
listProperty.addAll("1", "2", "3");
与听众
listProperty.addListener((ListChangeListener<? extends String> change) -> {
// e.g.
while (change.next()) {
if (change.wasAdded()) {
System.out.println(change.getAddedSubList());
}
}
});
这可能是一个在不破坏大量现有代码的情况下无法修复的错误:我不知道是否有计划纠正这个错误
实际发生的是,正在触发更改事件,但旧值和新值引用同一个列表(因为实际的包装列表引用没有更改)。因此,当然,
toString()
方法返回相同的值,无论您是从old
还是nw
调用它,并给出列表的当前内容。看起来像是可变数据的一般问题。更改列表实例的内容时,列表实例是相同的,因此旧值和新值都是对同一列表的引用,但由于通知是在修改后发生的,因此无论您使用哪个引用来访问列表,列表都会显示新内容,当然。我调试了它,看起来它来自com.sun.javafx.binding.ListExpressionHelper.fireValueChangedEvent(change)
。这种方法使旧值和新值相同。我认为你的推理是正确的。但是我已经阅读了以下内容(来自Learn Javafx8电子书):当列表的内容发生变化时,ChangeListeners的changed()方法接收到对与新旧值相同的列表的引用。如果ObservableList的包装引用被替换为新的引用,此方法将接收旧列表和新列表的引用。
是的,好的,这与我所说的基本相同。但是,我认为不应该在第一种情况下触发该事件,因为包装的引用没有更改。
listProperty.addListener((ListChangeListener<? extends String> change) -> {
// e.g.
while (change.next()) {
if (change.wasAdded()) {
System.out.println(change.getAddedSubList());
}
}
});
listProperty.setValue(FXCollections.observableArrayList("1","2","3"));