I was looking at an interface that is built into Java, and noticed that it has methods which return objects of its own type.
Specifically, the IntStream interface has a method range
which returns an IntStream object (i.e. some object that implements IntStream). This method can be used by only importing the interface, as follows:
import java.util.stream.IntStream;
class Foo {
public static void main(String[] args) {
IntStream s = IntStream.range(0,10);
System.out.println(s.average());
}
}
It therefore seems that 'under the hood' the interface is choosing an implementation for me, and allowing me to use it. How exactly is this working?
Crucially, how would I do the same thing? If I wanted to export an interface that can instantiate objects of its own type, so that a user could simply import my interface and it would drag along my implementation, how would I do this? Or is this only a special privilege of interfaces built into Java?
range
is a static method of theIntStream
interface that returns an instance of a class that implementsIntStream
. Take a look in the example below.In my example I tried to design something self-contained, but implementations of
createMagicInstance
may vary. You don't need to implement the returning type as a static inner class. I would recomend you to take a look at the source code ofIntStream
class of OpenJDK: https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/IntStream.java