また、閉じる必要のあるリソースを作成するjunitテストがあります。
このロジックを実装する1つの方法は、@Before
および@After
アプローチを使用することです。
私がしたことは、再利用するために作成をいくつかのユーティリティクラスにカプセル化することでした。例えば:
class UserCreatorTestUtil implements AutoClosable {
User create() {...}
void close() {...}
}
全体のポイントは、@After
でオブジェクトを閉じることを忘れずに、オブジェクトがそれ自体を閉じることです。
使用法は次のとおりです。
@Test
void test() {
try (UserCreatorTestUtil userCreatorTestUtil = new UserCreatorTestUtil()) {
User user = userCreatorTestUtil.create();
// Do some stuff regarding the user's phone
Assert.assertEquals("123456789", user.getPhone());
}
}
問題は、junitのassertキーワードがError
ではなくException
をスローすることです。
try-with-resourceはError
を「キャッチ」し、closeメソッドを呼び出しますか?
* try-with-resources documentation で答えが見つかりませんでした。
catch
なにもしません。しかし、finally
はすべてのリソースを閉じます。
finally
ブロック エラーがスローされた場合でも実行されます 。
基本的なtry-with-resourcesステートメントの擬似コードは(cf Java Language Specification §14.20.3.1
):
final VariableModifiers_minus_final R Identifier = Expression;
Throwable #primaryExc = null;
try ResourceSpecification_tail
Block
catch (Throwable #t) {
#primaryExc = #t;
throw #t;
} finally {
if (Identifier != null) {
if (#primaryExc != null) {
try {
Identifier.close();
} catch (Throwable #suppressedExc) {
#primaryExc.addSuppressed(#suppressedExc);
}
} else {
Identifier.close();
}
}
}
ご覧のとおり、Throwable
ではなくException
をキャッチしますが、これにはError
が含まれますが、でのみプライマリ例外を取得しますリソースを閉じるときに発生した例外を抑制された例外として追加するため。
また、リソースがfinally
ブロックで閉じられていることにも気付くことができます。つまり、彼らは何が起きても閉じられます( System.exit
もちろん、Error
またはThrowable
のサブクラスがスローされた場合でも、現在実行中のJava Virtual Machine)を終了します。
Try-with-Resourcesは、それ自体では何もキャッチしません。
ただし、catch
ブロックをtry-with-resourcesブロックの最後に追加して、好きなタイプのThrowable
をキャッチできます。
try (UserCreatorTestUtil userCreatorTestUtil = new UserCreatorTestUtil()) {
// ... Whatever
} catch (RuntimeException e) {
// Handle e.
} catch (Exception | Throwable t) {
// Handle t.
}
_try-with-resources
_の背後にある考え方は、リソースが閉じられるようにすることです。
従来の_try-catch-finally
_ステートメントの問題は、try
ブロックが例外をスローすると仮定しましょう。通常、この例外はfinally
ブロックで処理します。
ここで、finallyブロックでも例外が発生したとします。このような場合、try catchによってスローされる例外はlostであり、finally
ブロックで生成された例外が伝播されます。
_try {
// use something that's using resource
// e.g., streams
} catch(IOException e) {
// handle
} finally {
stream.close();
//if any exception occurs in the above line, than that exception
//will be propagated and the original exception that occurred
//in try block is lost.
}
_
_try-with-resources
_では、リソースのclose()
メソッドが自動的に呼び出されます。close()
が例外をスローした場合、残りのfinally
はそうではありません到達し、元の例外は失われます。
これと比較してください:
_try (InputStream inputStream= new FileInputStream("C://test.txt")){
// ... use stream
} catch(IOException e) {
// handle exception
}
_
上記のコードスニペットでは、close()
メソッドが自動的に呼び出され、そのclose()
メソッドも例外を生成した場合、その例外は自動的に抑制されます。
あなたの終わりの誤解:try-with-resourcesはnotdocatchを行います。
finalfinallyを行うため、「問題」の種類は関係ありません。
詳細については [〜#〜] jls [〜#〜] をご覧ください!