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 <marti...@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 ... > }