<div dir="ltr">I'm CC'ing Stuart Marks who has recently dealt with a similar issue when working on Sequenced Collections [1], and wrote a compatibility report [2] that includes an item about covariant overrides ("Covariant Overrides of `SequencedMap` View Collection Methods"), which is similar to what is discussed here. I contacted him off list to get his insights into the risks involved here.<div><br><div>To recap, ObservableMap inherits keySet(), entrySet() and values() from Map, which return the standard Set and Collection interfaces. ObservableMap should provide ObservableSet and perhaps the not-yet-existing ObservableCollection. There are 2 options here: one is to add additional default methods to ObservableMap that return observable collection, the second is to override the methods inherited from Map and change the return value. The latter has some backwards compatibility issues. It comes down to implementations of ObservableMap in the wild. I have yet to see any, personally. JavaFX does not itself expose any of its implementations, as ObservableMaps are obtained through FXCollections static methods.</div><div><br></div><div>I'd like to continue this discussion about the API side. I have already had some advances on the implementation.</div><div><div><br></div><div>[1] <a href="https://openjdk.org/jeps/431">https://openjdk.org/jeps/431</a></div><div>[2] <a href="https://bugs.openjdk.org/browse/JDK-8266572">https://bugs.openjdk.org/browse/JDK-8266572</a></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, May 31, 2022 at 12:02 AM Nir Lisker <<a href="mailto:nlisker@gmail.com">nlisker@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Then maybe a solution would be around adding new methods like observableKeySet(). These will need to be default methods, and the implementation could test if keySet() already returns an ObservableSet, in which case it returns it, and if not it wraps the Set in an ObservableSetWrapper or something like that.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, May 30, 2022 at 11:50 AM John Hendrikx <<a href="mailto:john.hendrikx@gmail.com" target="_blank">john.hendrikx@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Sorry, I misunderstood, I missed that the methods weren't already <br>
defined in ObservableMap, so no existing signature is changed.<br>
<br>
--John<br>
<br>
On 30/05/2022 09:39, Tom Schindl wrote:<br>
> Hi,<br>
><br>
> Well the binary compat IMHO is not a problem. If your subtype <br>
> overwrites the return type of a method the compiler will inserts a <br>
> bridge method:<br>
><br>
> Take this example<br>
><br>
> package bla;<br>
><br>
> import java.util.ArrayList;<br>
> import java.util.Collection;<br>
> import java.util.List;<br>
><br>
> public class Test {<br>
> public interface IB {<br>
> public Collection<String> get();<br>
> }<br>
><br>
> public interface I extends IB {<br>
> public List<String> get();<br>
> }<br>
><br>
> public class C implements I {<br>
> public ArrayList<String> get() {<br>
> return new ArrayList<String>();<br>
> }<br>
> }<br>
> }<br>
><br>
> if you look at C with javap you'll notice<br>
><br>
> Compiled from "Test.java"<br>
> public class bla.Test$C implements bla.Test$I {<br>
> final bla.Test this$0;<br>
> public bla.Test$C(bla.Test);<br>
> public java.util.ArrayList<java.lang.String> get();<br>
> public java.util.Collection get();<br>
> public java.util.List get();<br>
> }<br>
><br>
><br>
> The problem is more that if someone directly implemented ObservableMap <br>
> him/her self that it won't compile anymore. So it is a source <br>
> incompatible change.<br>
><br>
> Tom<br>
><br>
> Am 30.05.22 um 08:58 schrieb John Hendrikx:<br>
>> It's not binary compatible, as changing the return type results in a <br>
>> new method that compiled code won't be able to find.<br>
>><br>
>> See also "change result type (including void)" here: <br>
>> <a href="https://wiki.eclipse.org/Evolving_Java-based_APIs_2#Evolving_API_interfaces_-_API_methods" rel="noreferrer" target="_blank">https://wiki.eclipse.org/Evolving_Java-based_APIs_2#Evolving_API_interfaces_-_API_methods</a> <br>
>><br>
>><br>
>> --John<br>
>><br>
>> On 30/05/2022 03:22, Nir Lisker wrote:<br>
>>> Hi,<br>
>>><br>
>>> Picking up an old issue, JDK-8091393 [1], I went ahead and looked at <br>
>>> the<br>
>>> work needed to implement it.<br>
>>><br>
>>> keySet() and entrySet() can both be made to return ObservableSet rather<br>
>>> easily. values() will probably require an ObservableCollection<E> type.<br>
>>><br>
>>> Before discussing these details, my question is: is it backwards <br>
>>> compatible<br>
>>> to require that these methods now return a more refined type? I <br>
>>> think that<br>
>>> it will break implementations of ObservableMap out in the wild if it<br>
>>> overrides these methods in Map. What is the assessment here?<br>
>>><br>
>>> <a href="https://bugs.openjdk.java.net/browse/JDK-8091393" rel="noreferrer" target="_blank">https://bugs.openjdk.java.net/browse/JDK-8091393</a><br>
</blockquote></div>
</blockquote></div>