web-dev-qa-db-ja.com

Java 8 Streamインスタンスは常にclose()である必要がありますか?

Javadoc

ストリームにはBaseStream.close()メソッドがあり、AutoCloseableを実装していますが、ほとんどすべてのストリームインスタンスは、使用後に実際に閉じる必要はありません。通常、ソースがIOチャネル(Files.lines(Path、Charset)によって返されるものなど))であるストリームのみを閉じる必要があります。ほとんどのストリームは、コレクション、配列、または生成関数によってサポートされています、特別なリソース管理は必要ありません(ストリームに閉じる必要がある場合は、try-with-resourcesステートメントでリソースとして宣言できます)。

「ほぼすべて」と「一般的に」はあいまいです-ライブラリを作成していて、そのストリームのユーザーからストリームのソースを抽象化している場合、常にとにかく自分に質問しなければなりません-「私は閉じるべきですか」この?"端末操作はcloseを呼び出さないため、IOでサポートされたストリームを閉じる必要があります。したがって、事実上、常にストリームの送信元を覚えているか文書化するか、常にcloseを実行する必要があります。それ。

核となるオプションは、メソッドからStreamsを返さないか、Streamパラメーターを受け入れないことだと思います。これは、JDKチームの一部の人々から反響を受けている感情です。 Streamsの実用性を考えると、制限が多すぎることがわかりました。

ストリームを閉じる際のベストプラクティスは何ですか?よく似たコミュニティの質問に積極的に参加しているが、関連するものは何も見つからなかったJDKの人々からの回答をオンラインで探しました。

12
RuslanD

あなたが言ったように、Javaでは、どのリソースを解放する責任があるかを正確に知る必要があるので、適切なtry-catch-constructs、try-with-resourcesに入れるか、何らかの方法で委任することができます仕事。

GCに頼ってクリーンアップできるのは、100%純粋なメモリだけです。
他にいくつかのリソースがmight混入している可能性がある場合、合理的に実行できるのは、単に安全にプレイすることだけです。

6
Deduplicator

「ベストプラクティス」に関する限り、「リソースストリーム」を返すメソッドには命名規則を使用することをお勧めします。

ストリームをclose() edする必要がある場合は、ファクトリメソッドopen()またはopenStream()を呼び出します。 SDKによって確立された規則に従って、一時ストリームstream()を構築するメソッドを呼び出します。メソッドにjavadocを常に配置して、クライアントにclose()する必要があることを警告します。

public interface StreamingServer<RECORD> {
    /** 
     * Return a memory-efficient record stream from {@code source}.
     * Clients <em>must</em> call {@link Stream#close} to dispose the
     * stream.
     */
    Stream<RECORD> openStream(URI source) throws IOException;
}

SDK作成者がAutoCloseableをベースストリームクラスに配置することを選択していなかったらいいのにと思います。 ResourceStreamサブタイプは、AutoCloseableを簡単に実装するものであり、さまざまな規約を明確にしていたでしょう。次に、それを必要としないStreamを閉じることができず、静的分析ツールで誤って管理されている可能性のあるResourceStreamを検出できます。

コードベースの必要性(およびコードレビューの規則を適用する機能)に応じて、必要なストリームサブクラスを自分で確立できます。または、独自の静的分析ツールを構築する場合は、管理対象リソースを直接マークするメソッドアノテーション。

@RequiresClose
Stream<RECORD> openStream(URI source) throws IOException { ... }
5
Jason Trump