今日、私たちは先週話し合ったのとまったく同じテーマを持っています。先週、テーマはスタイリング剤と洗浄剤でした。これらの一般的な用途の1つは、リソースをクリーンアップすることです。このブログ投稿では、前の投稿の最後に示唆された、より優れたメソッドについてさらに詳しく説明します。
さまざまな理由により、使用後に手動で閉じる必要がある多くのリソースがあります。これは通常、オブジェクトに対してoffメソッドを使用して行われます。もちろん、リソースをリークしたり、アイテムを半分処理された状態のままにしたりしたくない場合は、最後のブロックにoffメソッドを配置することを検討します。たとえば、次のとおりです。
static List<Object> getDbValues() {
EntityManager em = getEntityManager();
try {
return em.createNativeQuery("SELECT * FROM myTable").getResultsList();
} finally {
em.close();
}
}
それだけです、かなりよさそうです。リソースを追加すると、混乱が生じ、エラーが発生しやすくなります。
static List<Object> getDbValues() {
OutputStream output = getOutputStream();
InputStream input = getInputstream();
try {
try {
// do work
} finally {
input.close();
}
} finally {
output.close();
}
}
これは、より粗く、追跡するのが難しくなり始めました。私もそれを正しくやっていますか?信じられない。失敗するのは簡単です。著者は、このパターンが長年にわたって彼の本のいずれかで台無しにされており、誰もそれを実現しなかったことを認めています。正しいコードを使用しても、エラー処理の微妙な点はうまく処理できません。例外が互いに上書きされ、発生したスタックトレースの貴重な情報が失われる可能性があります。この問題を処理するコードを書くことはできますが、コードは複雑で見苦しいため、だれもそれを書くことはできません。
したがって、Java 7では、リソースを試して、より良い答えを得ました。この構成により、自動シャットダウンを実装するクラスは、Javaでのシャットダウンを処理できます。したがって、上記の例は次のようになります。
try(InputStream input = new FileInputStream("file");
OutputStream output = new FileOutputStream("other")) {
// do work
}
これははるかに簡単です。前の例よりも多くを処理します。これは実際にはコードを保持する方法ではありません。上記のコードは、コンパイラによってより詳細な結果に変換されます。見てみましょう:
InputStream input = new FileInputStream("file");
Throwable var2 = null;
try {
OutputStream output = new FileOutputStream("other");
Throwable var4 = null;
try {
//do work
} catch (Throwable var27) {
var4 = var27;
throw var27;
} finally {
if (output != null) {
if (var4 != null) {
try {
output.close();
} catch (Throwable var26) {
var4.addSuppressed(var26);
}
} else {
output.close();
}
}
}
} catch (Throwable var29) {
var2 = var29;
throw var29;
} finally {
if (input != null) {
if (var2 != null) {
try {
input.close();
} catch (Throwable var25) {
var2.addSuppressed(var25);
}
} else {
input.close();
}
}
}
すごい!それは非常に激しくなりました。ただし、注意深く分析すると、それが目的どおりに動作しており、例外をより完全に処理できることがわかります。
最終的な考え。で、前のポスト私はツール言及ロンボクを。これは良いツールだと思います。ロンボクのトリックの袋の中に注釈があり@Cleanup
ます。上記と非常によく似た動作をするようです。では、これら2つの違いは何でしょうか。彼らが同じようなことをするのは正しいことですが、彼らはわずかに異なっています。主な違いは、@Cleanup
上記のように単純にtry-finallyの組み合わせを書き込むだけですが、例外処理を行う魔法は何もしません。したがって@Cleanup
、finallyブロックの安全性は確保されますが、特殊な例外処理は失われます。
だからあなたはそれを持っています。try-with-resourcesを使用します。よりシンプルでクリーンで安全なこの場所は、私が欠点をあまり見ない場所です。
から:https://dev.to//kylec32/effective-java-tuesday-prefer-try-with-resources-2om9