On Fri, 6 Nov 2020 03:05:45 GMT, Stuart Marks <sma...@openjdk.org> wrote:

>> @ePaul wrote:
>> 
>>> The Stream API works just as well with [third party] collection libraries 
>>> instead of the java.util ones, just using different collectors. Adding a 
>>> method which directly returns a java.util.List somewhat couples it to the 
>>> Java Collection API.
>>> 
>>> Now this was mentioned two and a half year ago. Did something change which 
>>> made this consideration irrelevant? I would expect at least some mention of 
>>> it in the discussion here.
>> 
>> The separation between streams and the java.util Collections Framework is a 
>> good design principle, but it isn't an ironclad rule. It's still easy to 
>> have streams create instances of other collections libraries using the 
>> Collector interface. What's different here is that the Collections Framework 
>> has "leaked into" streams a little bit more, so that they're now more 
>> interdependent. This doesn't seem to have any disadvantages; it seems 
>> unlikely that the Collections Framework will ever be unplugged from the JDK. 
>> However, the benefits are that a List is the closest thing we have to an 
>> unmodifiable array that also plays well with generics and that can be 
>> value-based; these benefits are considerable.
>
>> Simon Roberts wrote:
> 
>> This discussion of unmodifiable lists brings me back to the thought that
>> there would be good client-side reasons for inserting an UnmodifiableList
>> interface as a parent of LIst, not least because all our unmodifiable
>> variants from the Collections.unmodifiableList proxy onward fail the Liskov
>> substitution test for actually "being contract-fulfilling Lists".
> 
> At some point there probably will need to be a long article explaining all 
> the issues here, but at the moment the best writeup I have is this one:
> 
> https://stackoverflow.com/a/57926310/1441122
> 
> TL;DR there are a few different ways to approach retrofitting something like 
> this, but they all have enough compromises that the net benefits are unclear.

Hi Stuart,

I would like to discuss the serialization. You introduce new 
CollSer.IMM_LIST_NULLS type of immutable collection. This means that if this 
change goes into JDK16 for example, JDK15 and before will not be able to 
deserialize such list as they know nothing about IMM_LIST_NULLS even if such 
lists don't contain nulls. The reason you say to chose new type of 
serialization format is the following:

> "Suppose I had an application that created a data structure that used lists 
> from List.of(), and I had a global assertion over that structure that it 
> contained no nulls. Further suppose that I serialized and deserizalized this 
> structure. I'd want that assertion to be preserved after deserialization. If 
> another app (or a future version of this app) created the structure using 
> Stream.to
>  List(), this would allow nulls to leak into that structure and violate that 
> assertion. Therefore, the result of Stream.toList() should not be 
> serialization-compatible with List.of() et. al. That's why there's the new 
> IMM_LIST_NULLS tag in the serial format"

I don't quite get this reasoning. Let's try to decompose the reasoning giving 
an example. Suppose we had the following data structure:

public class Names implements Serializable {
  private final List<String> names;
  Names(List<String> names) {
    this.names = names;
  }
  public List<String> names() { return names; }
}

App v1 creates such structures using new Names(List.of(...)) and 
serializes/deserializes them. They keep the invariant that no nulls are 
present. Now comes App v2 that starts using new Names(stream.toList()) which 
allows nulls to be present. When such Names instance from app v2 is serialized 
and then deserialized in app v1, nulls "leak" into data structure of app v1 
that does not expect them.

But the question is how does having a separate CollSer.IMM_LIST_NULLS type 
prevent that from happening?

-------------

PR: https://git.openjdk.java.net/jdk/pull/1026

Reply via email to