倭マン's BLOG

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

Stream インターフェースの親である BaseStream がちゃんとある

以前の記事『Stream インターフェースの親として BaseStream というのがあるようで・・・』で java.util.stream.Stream インターフェースの親タイプとして BaseStream というのがあるようだが公開されてないか削除された、ということを書きましたが、java8-ea-b120 で久し振りに確かめたら普通にそういうインターフェースが public なインターフェースとして存在しているようで。 しかもメソッドが増えてるし。 ということで BaseStream がどんな定義なのかもう一度見ていきましょう。

インターフェース定義

まずは BaseStream インターフェースの定義:

package java.util.stream;

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

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

    @Override void close();
    S onClose(Runnable closeHandler);

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

    boolean isParallel();

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

前回から変わっているのは

  • AutoCloseable を拡張している
  • close(), onClose() メソッドが追加されている

です。 java.lang.AutoCloseable インターフェースは以下のような定義です:

package java.lang;

public interface AutoCloseable{

    void close() throws Exception;
}

これは try-with-resouces 文とともに使って、処理中に例外が発生した場合でも close() メソッドが確実に呼ばれることを保証する型です*1。 BaseStream インターフェースでは close() メソッドがオーバーライドされて例外が投げられなくなってます*2。 onClose() メソッドはストリームを閉じるときのフック・メソッドで、行いたい追加処理を Runnable オブジェクトとして渡します。 まぁ、ラムダ式を使って書くことが多くなるんじゃないかなぁ。

ちなみに、これら以外のメソッドは前回の記事を書いた時点で存在してましたが、細かい仕様の変更とかまで確認してません^ ^;)

Stream インターフェースとの関係

Stream インターフェースは、上記の BaseStream を使って

package java.util.stream;

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

と定義されています。 BaseStream に定義されている sequential(), parallel(), unordered(), onClose() メソッドは、型パラメータの2つ目の型 (S) が返されるので、Stream ではこれらの返り値のメソッドは Stream<T> になります。

まぁ、ジェネリクスが導入されてから、サブタイプでメソッドの(自分と同型の)返り値の型範囲を狭めたいときによくやる設計、って感じですね。 前に見たときに JavaDoc がおかしくなってたのは何だったんだろう・・・?

Scalaスケーラブルプログラミング第2版

Scalaスケーラブルプログラミング第2版

*1:そう言えば、id:nowokay 氏の『Java8で複数の処理を確実に実行するイディオム』で try-with-resouces 文を使ってたのはこの機能のためなのね。 そこでは java.io.Closeable (java.lang.AutoCloseable のサブタイプ)を使ってますが。 あっと、別に Stream や BaseStream は関係ないです。

*2:AutoCloseable インターフェースの JavaDoc に、サブタイプでは例外の型を狭めるか例外を投げないようにオーバライドすべし、と書いてますね。