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>