您現在處於正確的軌道上:包裝程序列表會將弱偵聽程序添加到包裝列表中,以避免內存泄漏,並且如果您不包含對包裝程序列表的引用,它將被垃圾收集。
看到這個測試(從here拍攝):
private ObservableList<String> s = FXCollections.observableArrayList();
@Override
public void init() throws Exception {
FXCollections.unmodifiableObservableList(s).addListener((ListChangeListener.Change<? extends String> c) ->
System.out.println(c));
s.setAll("A1");
s.setAll("A2");
System.gc();
s.setAll("A3"); // <- Doesn't trigger the listener
}
它打印:
{ [A1] added at 0 }
{ [A1] replaced by [A2] at 0 }
但如果添加到列表的引用:
private ObservableList<String> s = FXCollections.observableArrayList();
@Override
public void init() throws Exception {
// create a reference
final ObservableList<String> wrapperList = FXCollections.unmodifiableObservableList(s);
wrapperList.addListener((ListChangeListener.Change<? extends String> c) ->
System.out.println(c));
s.setAll("A1");
s.setAll("A2");
System.gc();
s.setAll("A3"); // <- Triggers the listener
}
現在它打印:
{ [A1] added at 0 }
{ [A1] replaced by [A2] at 0 }
{ [A2] replaced by [A3] at 0 }
所以基本上我需要的時候我回到有將堅持在除了原有的可觀察名單本身不可改變觀察到列表的引用附加字段屬性,並抑制警告不可變的領域。這不是開發者友好的。還有其他選擇嗎? –
這是它被設計的方式。如果您查看了我發佈的鏈接(https://bugs.openjdk.java.net/browse/JDK-8088454),那麼這是推薦的解決方案。 –
@StéphaneAppelcel:這個方法也與我的發現一致(在這裏)(https://stackoverflow.com/a/44343112/230513),儘管我歡迎任何額外的見解。 – trashgod