倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

Stream インターフェースの親として BaseStream というのがあるようで・・・

Java 8 ea-b90 の話ですが、java.util.stream.Stream インターフェースのスーパーインターフェースとして、java.util.stream.BaseStream というインターフェースがあるようです。 java.util.stream の package private なインターフェースなので直接参照することはできませんが、昔は public だったせいか、java.util.stream パッケージの JavaDoc などに名残(というか修正忘れだろうけどw)がちらほらと。 逆アッセンブルとか逆コンパイルとかはあんまりやり方分からないのでリフレクション使ってちまちまクラス宣言やメソッドを解読(?)してみると、大体以下のような感じのインターフェースのようです:

package java.util.stream;

import java.util.Iterator;
import java.util.Spliterator;

interface BaseStream<T, S extends BaseStream<T, S>>{

    Iterator<T> iterator();
    Spliterator<T> spliterator();

    boolean isParallel();

    S sequential();
    S parallel();
    S unordered();
}

どれもデフォルトメソッドではありません。 seqential(), parallel(), unordered() の返り値が S 型になっていて、これはクラス宣言の第2型パラメータによって指定されています。 Stream インターフェースは、この BaseStream を使って以下のように定義されています(メソッド宣言は省略):

package java.util.stream;

public interface Stream<T> extends BaseStream<T, Stream<T>>{
    ...
}

さて、上記の BaseStream, Stream の定義から、Stream の sequential(), parallel(), unordered() の宣言は

    Stream<T> sequential();
    Stream<T> parallel();
    Stream<T> unordered();

となっているべきですが、JavaDoc (Java 8 ea-b90) を見ると返り値が S 型のままになっとる*1。 JavaDoc で package private の型が public な型の宣言に出てくるなんておかしくない?*2 まさか、Java8 からなんらかの新しい文法が導入されたとか?*3

Java言語仕様 第3版 (The Java Series)

Java言語仕様 第3版 (The Java Series)

*1:Java8 ea-b91 でも同じ。

*2:出てくるように指定はできるけど、そのように指定すると BaseStream インターフェース自体も JavaDoc に出てくるハズ。

*3:Java 5 あたりでメソッドをオーバーライドする際に、メソッドの戻り値がサブタイプでよくなった共変戻り値みたく。