JDK-8134373 : use collections convenience factories in the JDK
  • Type: Sub-task
  • Component: core-libs
  • Sub-Component: java.util:collections
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2015-08-25
  • Updated: 2017-05-17
  • Resolved: 2016-10-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b141Fixed
Description
Explore the potential uses of convenience Factory Methods for Collections (List.of(), Map.ofEntries(), etc) within the JDK.

There are probably places in the JDK where collections are created and initialized with contents and are thereafter not changed. They're effectively immutable. They might or might not be wrapped with the unmodiable wrappers. But, searching for calls to Collections.unmodifiable*() might prove fruitful at turning up locations where the convenience factories could be used.

There are probably a bunch of places where lists are initialized using Arrays.asList(). It might be reasonable to look for these locations and to investigate replacing them with calls to List.of().

Bear in mind that the immutable collections returned by the convenience factories have different semantics from collections wrapped with the unmodifiable wrappers. One is that the original collections are still modifiable by anyone who keeps a reference to them. Another is that the iteration order of the new sets and maps differs (in fact, the iteration order changes randomly).

The List returned by Arrays.asList() is actually mutable, but it cannot change size (i.e., no adds or removes are permitted). However, the List returned by List.of() is truly immutable. In addition, calling List.of() unavoidably creates a copy of its input array, for sizes larger than 2, which may be a performance concern.

These issues represent potential incompatibilities and must be investigated or tested. Therefore, while the convenience factories are probably useful in many cases, they aren't necessarily a drop-in replacement for Collections.unmodifiable*(...) and Arrays.asList().
Comments
Review threads: http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-September/043484.html http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-October/043943.html There are some potentially application-visible changes here, for which a CCC should be filed. The primary issue is potential serialization incompatibility. 1. java.net.CookieManager.get() -- often called via CookieHandler.get() -- returns a different Map implementation. 2. java.util.ResourceBundle.Control has some final fields of the List<String>: FORMAT_DEFAULT, FORMAT_CLASS, and FORMAT_PROPERTIES. These are now a different List implementation. 3. The specification for the above fields of ResourceBundle.Control *links* to Collections.unmodifiableList(), which implies that the fields are instances returned by that method. Indeed, they are, but it's unclear whether that was intended to be part of the specification. This change removes the link and instead merely states that the Lists are unmodifiable.
11-10-2016

Daniel's comment above raises a good issue. Some of the classes in the JDK are serializable. The general rule is that such classes should be backward *and forward* serialization compatible. That is, if an instance of such a class is serialized on JDK N, it should be deserializable on JDK N+1 and also on JDK N-1, if that class existed in JDK N-1. If such a class contains a non-transient collection field, that collection instance is part of the class' serialization format. Thus, such an instance must not be replaced with an instance from the new collection factories, as that would constitute an incompatible change to the serialization format.
15-09-2016

Another potential incompatibility is with serialization: if I'm not mistaken, earlier versions of the JDK will not be able to deserialize lists created by List.of() etc... So using List.of() to assign a non transient field of a serializable object should be avoided.
15-09-2016