Use of super in type parameters

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

I have encountered on 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
        <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> 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"
> ?
> 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