Use of super in type parameters

Zhong Yu zhong.j.yu at gmail.com
Mon Apr 15 12:50:31 PDT 2013


I have encountered on stackoverflow.com several legit use cases of
lower bound. And the other day Ali Lahijani raised the question that
Stream.reduce(BinaryOperator) breaks convariance of Stream, and I
thought that the root problem is lack of lower bound - the method
would have had a better signature
    Stream<T>
        <U super T> Optional<U> reduce(BinaryOperator<U> accumulator)
So I don't think there's a lack of use cases for lower bound. (But I
have no idea how difficult it is to support it)

Zhong Yu


On Mon, Apr 15, 2013 at 2:37 PM, Martin Buchholz <martinrb at google.com> wrote:
> CompletableFuture currently has a method like this:
>
>     public CompletableFuture<Void> acceptEither
>         (CompletableFuture<? extends T> other,
>          Consumer<? super T> block) {
>         return doAcceptEither(other, block, null);
>     }
>
> But that signature is not quite correct (not as general as it could be).
>  The "correct" signature is
>
>     public <U super T> CompletableFuture<Void> acceptEither
>         (CompletableFuture<? extends U> other,
>          Consumer<U> block) {
>         return doAcceptEither(other, block, null);
>     }
>
> but that fails to compile, because type parameters can only be constrained
> by extends, not super.  Is implementing this on the radar?  Angelika claims
> "lower bounds for type parameters make no sense"
> http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#Why%20is%20there%20no%20lower%20bound%20for%20type%20parameters
> ?
>
> but I am finding that hard to believe.  Is she right? For comparison,  the
> equivalent static method can be made to do what we want:
>
>     public static <U> CompletableFuture<Void> acceptEither
>         (CompletableFuture<? extends U> f,
>          CompletableFuture<? extends U> other,
>          Consumer<U> block) {
>         return ...
>     }


More information about the lambda-dev mailing list