Works by

Ren's blog

@rennnosuke_rk 技術ブログです

【Java】ByteArrayOutputStreamのclose()実装

Closable

Java の Closable インタフェースを実装した具象クラスは、 close() メソッドを定義する必要がある。
Closable を実装した抽象クラスに Writer 、継承したインタフェースには OutputStream があり、これらの抽象 I/O を実装したクラスでは確保した出力先リソースを開放するために close() メソッドを呼ぶ。

例えば、 Writer を実装した FileWriter は、以下のように実装された close() を使用する。
具体的には、 FileWriter は継承する OutputStreamWriter のコンポジットオブジェクトである StreamEncoderメンバの close() メソッドを呼ぶ。

public void close() throws IOException {
    synchronized (lock) {
        if (closed)
            return;
        implClose();
        closed = true;
    }
}

排他制御の下、リソースの開放処理が行われる。
ちなみに、 close() の仕様にもあるように、すでに開放された状態で再度 close() を呼び出しても何も起こらない。

Closable

void close() throws IOException このストリームを閉じて、それに関連するすべてのシステム・リソースを解放します。ストリームがすでに閉じられている場合は、このメソッドを呼び出しても何の効果もありません。 AutoCloseable.close()で説明されているように、クローズが失敗する可能性がある場合は慎重な注意が必要です。IOException をスローする前に、基礎となるリソースを解放することと、Closeable をクローズ済として内部的にマークすることをすることを強くお薦めします。

ByteArrayOutputStream

バイト列を出力する ByteArrayOutputStream も同様に OutputStream を実装しており、 close() を以下のように実装している。

/**
 * Closing a {@code ByteArrayOutputStream} has no effect. The methods in
 * this class can be called after the stream has been closed without
 * generating an {@code IOException}.
 */
public void close() throws IOException {
}

何もしていない。そのため、 close() をコールしても何も起こらない。
このことから、生成した ByteArrayOutputStream に対する close 処理は不要。ただし、 OutputStream のような抽象型でオブジェクトを取り扱う場合でも close() して問題ない。