Why Stream.concat is a static method - type variable contravariance
james at lightbend.com
Thu Oct 11 04:06:23 UTC 2018
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
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
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.
*Senior Developer, Office of the CTO*
Lightbend <https://www.lightbend.com/> – Build reactive apps!
Twitter: @jroper <https://twitter.com/jroper>
More information about the core-libs-dev