RFR(m): JEP 269 initial API and skeleton implementation (JDK-8139232)

Peter Levart peter.levart at gmail.com
Tue Nov 24 16:55:42 UTC 2015


Hi Stuart,

Since those factory methods construct general purpose immutable 
collections, I miss methods that act as copy constructors (general 
purpose collection implementations should have them, says recommendation):


public static <E> List<E> copyOf(Collection<? extends E> collection);

public static <E> Set<E> copyOf(Collection<? extends E> collection);

public static <K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> map);


Sometimes it would be useful also to trust the copy to contain elements 
of the specified type (since those are immutable collections, Class 
arguments are needed only at construction time to do the check while 
constructing):


public static <E> List<E> copyOf(Collection<? extends E> collection, 
Class<E> elementType);

public static <E> Set<E> copyOf(Collection<? extends E> collection, 
Class<E> elementType);

public static <K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> map, 
Class<K> keyType, Class<V> valueType);


As an optimization, those copyOf methods could be specified to return 
the passed-in collection if it was already of the correct "immutable" type:

List<String> strings = List.of("a", "b", "c");
assert List.copyOf(strings) == strings;
assert List.copyOf(strings, String.class) == strings; // just checks the 
elements


This is different from Collections.immutableXXX(xxx) since the later can 
not be used to make "defensive" copies. For example:


class SomeBean {
     Set<Option> options = Set.of();

     Set<Option> getOptions() {
         return options;
     }

     void setOptions(Set<Option> options) {
         this.options = Set.copyOf(options, Option.class);
     }
}


Or would that be beyond the scope of this JEP?

Regards, Peter


On 11/24/2015 07:26 AM, Stuart Marks wrote:
> Hi all,
>
> Please review these API and implementation changes that comprise the 
> first integration of JEP 269. I intend to push this under the "initial 
> API and skeleton implementation" subtask, JDK-8139232.
>
> Changes since the previous review:
>  - more precise wording regarding static factory methods (thanks Remi)
>  - add defensive copy and test for List.of(E...) (thanks Michael Hixson)
>  - more null checking and tests
>  - various small wording cleanups
>  - @since 9
>
> I've left the fixed-arg overloads at ten for all three interfaces. The 
> fixed-arg methods provide a useful fast path for initialization and 
> non-desktop, non-server cases. The cost is some API clutter; ten 
> elements or pairs is rather a lot. This number should be sufficient, 
> though, to handle the vast majority of cases without having to switch 
> to varargs. Note that the clutter is only in the API definitions, and 
> it doesn't intrude into the point of call (at least for List and Set). 
> For the Map case, it's particularly useful to have lots of fixed-arg 
> overloads, since the varargs case requires switching APIs and adding 
> more boilerplate.
>
> I've also updated the JEP text to reflect the current proposal, mainly 
> the removal of the static factory methods from the concrete classes.
>
> JEP:
>
>     http://openjdk.java.net/jeps/269
>
> API spec (basically List, Map, and Set):
>
>     http://cr.openjdk.java.net/~smarks/reviews/jep269/api.20151123/
>
> Specdiff:
>
>     http://cr.openjdk.java.net/~smarks/reviews/jep269/specdiff.20151123/overview-summary.html 
>
>
> Webrev:
>
>     http://cr.openjdk.java.net/~smarks/reviews/jep269/webrev.20151123/
>
> Thanks,
>
> s'marks




More information about the core-libs-dev mailing list