ping ! Rémi
----- Mail original ----- > De: "Remi Forax" <[email protected]> > À: "core-libs-dev" <[email protected]> > Envoyé: Mardi 13 Novembre 2018 15:47:54 > Objet: Both Collector.of() are not correctly typed > Last year, > a student of mine as remarked that the two variants of Collector.of() are not > correctly typed (the wildcards are missing) > and obviously, this year it's one of my teaching assistant that has found > exactly the same issue. > So let's fix this issue. > > Adding the wildcards is both source and binary backward compatible in this > case > - the methods of are static (so no overriding possible) > - the wildcards types are super types of the types of current version, so it > will not break at use sites and > - the erased signature is the same so it's a binary backward compatible > change. > > The right code is > @SuppressWarnings("unchecked") > public static<T, R> Collector<T, R, R> of(Supplier<? extends R> supplier, > BiConsumer<? super R, ? super T> > accumulator, > BinaryOperator<R> combiner, > Characteristics... > characteristics) { > Objects.requireNonNull(supplier); > Objects.requireNonNull(accumulator); > Objects.requireNonNull(combiner); > Objects.requireNonNull(characteristics); > Set<Characteristics> cs = (characteristics.length == 0) > ? Collectors.CH_ID > : > > Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH, > > characteristics)); > return new Collectors.CollectorImpl<>((Supplier<R>)supplier, > (BiConsumer<R, > T>)accumulator, combiner, cs); > } > and > @SuppressWarnings("unchecked") > public static<T, A, R> Collector<T, A, R> of(Supplier<? extends A> > supplier, > BiConsumer<? super A, ? super > T> accumulator, > BinaryOperator<A> combiner, > Function<? super A, ? extends > R> finisher, > Characteristics... > characteristics) { > Objects.requireNonNull(supplier); > Objects.requireNonNull(accumulator); > Objects.requireNonNull(combiner); > Objects.requireNonNull(finisher); > Objects.requireNonNull(characteristics); > Set<Characteristics> cs = Collectors.CH_NOID; > if (characteristics.length > 0) { > cs = EnumSet.noneOf(Characteristics.class); > Collections.addAll(cs, characteristics); > cs = Collections.unmodifiableSet(cs); > } > return new Collectors.CollectorImpl<>((Supplier<R>)supplier, > (BiConsumer<R, > T>)accumulator, combiner, (Function<A, R>)finisher, cs); > } > > You may ask why the code is safe given there are now some > @SuppressWarnings("unchecked"), it's because for a functional interface, > the parameter types are contra-variant and the return type is covariant. > > At one point in the future, perhaps JEP 300 [1] will be implemented, in that > case we will be able to remove the @SuppressWarnings. > > You may also notice that, we may want at the same time replace the > unmodifiableSet(EnumSet.of() + add) with Set.of(), > i've not done that change given it's not related to the typing issue. > > cheers, > Rémi > > [1] https://openjdk.java.net/jeps/300
