6

ソースコードが入手できない、文書化が不十分なサードパーティのライブラリを使用しているとしましょう。ライブラリのメソッドの 1 つは、InputStreamさまざまなデータをロードするために を受け入れます。

ドキュメントが不足しているため、メソッドがストリームの処理が完了したときにストリームを閉じるかどうかは明確ではありません。そのため、考えられる解決策の 1 つは、安全のために、try-with-resource で呼び出しをラップすることです。

残念ながら、Java の仕様では (私の知る限り)、try-with-resource 内でリソースが手動で閉じられた場合に何が起こるかについては言及されていません。誰かがたまたま知っていますか?

4

4 に答える 4

10

リソース自体の実装に完全に依存します。close()try-with-resource ステートメントは、ブロック内で呼び出すfinally(および例外を保持するなど)ための "単なる" 構文糖衣 (しかし、とても甘い) です。

ストリームが 2 回呼び出されることをサポートしている限り (close()ほとんどの実装ではそうであると思いますが、InputStreamrequires のコントラクトでも問題ありません)、まったく問題ありません。

あるリソースを別のリソース内にラップするおなじみの場合とまったく同じ状況になることに注意してください。

try (InputStream input = new FileInputStream(...)) {
   try (Reader reader = new InputStreamReader(input, ...)) {
       ...
   }
}

または、単一の try-with-resources ステートメントを使用します。

try (InputStream input = new FileInputStream(...);
     Reader reader = new InputStreamReader(input, ...)) {
   ...
}

どちらの場合も 2 つのfinallyブロックが存在するため、最初reader.close()に呼び出され、次に呼び出されますinput.close()が、とにかくreader.close()閉じます。input

于 2014-01-21T09:54:20.940 に答える
6

close()のメソッドCloseable(したがって、 のInputStream) は冪等である必要があります。

ストリームが既に閉じられている場合、このメソッドを呼び出しても効果はありません。

したがって、InputStream複数回閉じても安全です。

ただし、より一般的なAutoCloseableインターフェイスでは、そのclose()メソッドがべき等である必要はありません。したがって、 以外のリソースに対して同じことを行うのは安全ではない可能性がありますCloseable

Closeable の close メソッドとは異なり、この close メソッドはべき等である必要はないことに注意してください。つまり、この close メソッドを複数回呼び出すと、目に見える副作用が生じる可能性があります。これは、複数回呼び出されても効果がないことが必要な Closeable.close とは異なります。ただし、このインターフェイスの実装者は、close メソッドを冪等にすることを強くお勧めします。

于 2014-01-21T09:56:31.260 に答える
2

仕様には、できることはすべて記載されていますresource.close()。例外がスローされる場合、その例外はコンストラクトからスローされます。

もちろん、仕様では、特定のcloseメソッドが例外をスローするかどうかを知ることはできません。それを見つけるには、特定のリソースをテストする必要があります。

于 2014-01-21T09:55:09.207 に答える
0

最終ステートメントでそれを閉じることを試みることができます。

InputStream stream = null;
try {
  stream = new InputStream();
  yourMethod(stream);
} catch (...) {

} finally {
  try {
    stream.close()
  } catch (IOException ioe) {
    // can throw IOException while closing closed stream
  }
}
于 2014-01-21T09:55:33.393 に答える