Is this the problem discussed here? http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#Lower%20Bound%20Type%20Parameters%20of%20Methods (I think I ran into this myself and think the java language should be fixed to allow "Lower Bound Type Parameters of Methods")
On Wed, Oct 10, 2018 at 9:06 PM, James Roper <ja...@lightbend.com> wrote: > With the work I'm doing at the moment at creating a Reactive Streams > equivalent to java.util.stream, I've often wondered why Stream.concat is a > static method, rather than an instance method concating the given stream > onto this. But I think the reason has just dawned on me, and I wanted to > confirm that I'm correct. > > Java doesn't support contravariant type variables - it does for type > declarations, but not type variables. > > To put more concretely, if I had a Stream<Integer>, and I wanted to concat > a Stream<Number>, this is a valid thing to do, the resulting stream would > be Stream<Number>. But doing that with an instance method would require > something like this: > > public <S super T> Stream<S> concat(Stream<? extends S> b); > > Which is not supported (specifically, <S super T> type variable declaration > is not supported). In contrast, what we have in the actual API: > > public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends > T> b); > > does allow me to concat a Stream<Integer> and Stream<Number> with a > resulting type of Stream<Number>. > > Is this right, or are there other reasons? Also, is there any possibility > that Java might support contravariance in type variables in future? My > reason for wanting it is to provide the following method for reactive > streams: > > public <S super T> Publisher<S> onErrorResumeWith(Function<? super > Throwable, ? extends Publisher<? extends S>> f); > > The intent of this method is when a stream encounters an error, the passed > function is invoked with the error, and that function returns a publisher > that gets concated to the current stream instead of the error being > emitted. This could possibly be implemented with a static method: > > public static <T> Publisher<T> onErrorResumeWith(Publisher<? extends T> a, > Function<? super Throwable, ? extends Publisher<? extends T> f); > > But unlike concat, this method feels and reads much better as an instance > method, as a static method it's a little confusing. > > Regards, > > James > > -- > *James Roper* > *Senior Developer, Office of the CTO* > > Lightbend <https://www.lightbend.com/> – Build reactive apps! > Twitter: @jroper <https://twitter.com/jroper> >