Ali*_*aka 53 java junit exception-handling exception
我有一些junit测试可以创建一些应该关闭的资源.
实现此逻辑的一种方法是使用@Before和@After方法.
我所做的是将创建封装在一些实用程序类中以供重用.例如:
class UserCreatorTestUtil implements AutoClosable {
User create() {...}
void close() {...}
}
Run Code Online (Sandbox Code Playgroud)
关键是对象要关闭自己,而不是需要记住关闭它@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());
}
}
Run Code Online (Sandbox Code Playgroud)
问题是junit的assert关键字抛出Error- 而不是Exception.
try-with-resource会"捕获" Error并调用close方法吗?
*在try-with-resources文档中找不到答案.
Thi*_*ilo 73
它catch什么都没有.但它确实finally关闭了所有资源.
finally即使抛出错误,也会运行块.
Nic*_*tto 37
基本的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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的那样,它捕获的Throwable不是Exception包含Error但只是为了获取主要异常,以便将关闭资源时发生的任何异常添加为抑制异常.
您还可以注意到您的资源在finally块中被关闭,这意味着它们将被关闭,无论发生什么情况(System.exit当然,当它终止当前运行的Java虚拟机时),即使在抛出一个Error或任何子类的情况下Throwable也是如此.
And*_*ner 12
尝试使用资源不会捕获任何内容.
但是,您可以将catch块附加到try-with-resources块的末尾,以捕获Throwable您喜欢的任何类型:
try (UserCreatorTestUtil userCreatorTestUtil = new UserCreatorTestUtil()) {
// ... Whatever
} catch (RuntimeException e) {
// Handle e.
} catch (Exception | Throwable t) {
// Handle t.
}
Run Code Online (Sandbox Code Playgroud)
背后的想法try-with-resources是确保资源应该关闭.
常规try-catch-finally语句的问题是让我们假设你的try块抛出一个异常; 现在通常你会在finally块中处理该异常.
现在假设finally块中也发生异常.在这种情况下,try catch抛出的异常将丢失,并且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.
}
Run Code Online (Sandbox Code Playgroud)
在资源try-with-resources的close()方法中将自动调用,如果close()抛出任何异常,finally则不会到达其余部分,并且原始异常将丢失.
与此形成鲜明对比:
try (InputStream inputStream= new FileInputStream("C://test.txt")){
// ... use stream
} catch(IOException e) {
// handle exception
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码片段中,该close()方法会自动被调用,如果该close()方法也生成了任何异常,则该异常将自动被抑制.
另请参见:Java语言规范14.20.3
| 归档时间: |
|
| 查看次数: |
5028 次 |
| 最近记录: |