3

C# では、 のメソッドで例外をスローすることは悪い習慣と見なされています。DisposeIDisposable

対照的に、Java では、 のcloseメソッドはAutoCloseable、例外がスローされることを許可し、呼び出し元に何らかの方法でそれを処理するように強制します。しかし、これが発生した場合、発信者は何をすることが合理的に期待されるのでしょうか? これは、リソースを閉じようとして失敗したことを示しています。ユーザーは続行する前に、おそらくある種の指数バックオフを使用して、リソースを再度閉じる必要がありますか?

4

3 に答える 3

1

usingJava の設計者は、独自の try-with-resources 機能を実装する前に、.NET のブロックのクリーンアップ例外処理で発生した問題を確認できたため、それを改善することができました。.NET では、Disposeブロックの作成者は、発生した例外を飲み込むか、呼び出し元のプログラムにすべてが正常であると誤って信じ込ませるか、例外Disposeの証拠をすべて消去するような方法で例外を浸透させるかの不快な選択に直面することがよくあります。以前の例外。幸いなことに、Java はその問題を回避します。

try-with-resources ブロックが正常に成功し、closeも正常に成功した場合、外部コードはすべてを正常と見なします。tryその部分で例外が発生してもclose正常に成功した場合、外部コードは try-block 例外を参照します。が正常にtry完了しても例外が発生した場合close、外部コードでclose例外が発生します。また、tryスローだけでなくcloseスローも行う場合、外部コードはtry例外を認識しますが、内部で発生した例外を取得することもできますclose(複数のネストされた try-with-resources が実行中closeに例外をスローすると、スローされたすべての例外が外部コードで利用可能になります) )。

その結果、.NET の設計では、.NET によってスローされた潜在的に深刻な例外を抑圧することがよくありますがDispose、Java の設計ではclose、呼び出し元がすべてが正常であると信じることができないほど、何かが十分にうまくいかない場合は常に例外をスローすることを好みます。

于 2014-10-21T15:27:28.170 に答える
1

の設計AutoCloseableは、Java のチェック例外の結果です。一部の実装では、チェックされた例外をスローできなければならないだけであり、そのthrows Exception必要があります。ただし、実装では、スローされるより具体的な型を宣言する必要があります(存在する場合)。

このインターフェイス メソッドは throw と宣言されていますExceptionが、実装者はメソッドの具体的な実装を宣言してより具体的な例外をスローするか、閉じる操作が失敗しない場合は例外をまったくスローしないことを強くお勧めします。close

回避する方法がある場合は例外をスローすべきではありませんが、常に回避できるとは限りません。たとえば、BufferedOutputStreamフラッシュされていないデータで を閉じる場合、バッファリングされたストリームには 2 つのオプションがあります。書き込まれていないデータを無視して閉じるか、ストリームに書き込むと、例外がスローされる可能性があります。

于 2014-10-20T07:21:12.987 に答える
0

暗黙の close() 呼び出しを含む、リソースに関係するすべての操作は、try{} ブロックの一部と見なされているようです。技術的/構文的に考えても、リソースは {} 括弧の外側に記載されています。

close() 中に IOException がスローされた場合、try に関連付けられたいくつかの catch() 句によってキャッチされる (または伝播する) ことを意味します。

例外をスローする必要がある理由について: close() は flush() を引き起こす可能性があり、flush() は write() を引き起こす可能性があり、write() が失敗する可能性があります。

于 2014-10-20T07:18:27.107 に答える