Why couldn't it?
This is a trick used in many places, for example enums, which are defined as:
public abstract class Enum<E extends Enum<E>>
The general idea is to establish a type parameter that represents your own type.
That's why that parameter's letter is S. That stands for "Self".
Hence, if we look at DoubleStream
, it is defined as:
public interface DoubleStream extends BaseStream<Double, DoubleStream> {}
The point of doing this is for 'self returning' methods, or at least, for methods that need to return the same type. There are loads of those in the stream concept, such as peek
, or limit
, or onClose
.
You could just.. not do that, and define things as follows:
public interface BaseStream<T> {
BaseStream parallel();
}
But the problem is, this downgrades types. If I have an IntStream
and I invoke .parallel()
on it, the compiler thinks the type of that is BaseStream
. This isn't usually relevant (in that IntStream
can tighten the return type, that's valid as per the Java Lang Spec), but sometimes it is.