java - (何时)try-with 是否应该包含 AutoCloseable 构造函数?

标签 java try-catch

Oracle Java documentation for the then-new try-with-resources显示了所有在 try(...) 中构建的 AutoCloseable 示例:

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
    ...
}

从某种意义上说,这似乎是安全的,即使构造函数(与某些后续事件相反)已经获取了必须释放的资源,如果我们遇到异常,它们也会被释放。

但是,例如 https://www.baeldung.com/java-try-with-resources指出,从 Java 9 开始,我们可以有效地使用在 try(...) 之前初始化的最终资源:

FileOutputStream fos = new FileOutputStream("output.txt");
try (fos) { 
    // do stuff
}

在类似的 Java-9 之前,我看到了:

CustomStreamLikeThing connection = new CustomStreamLikeThing("db_like_thing");
// ... do some stuff that may throw a RuntimeException
try (CustomStreamLikeThing connection2=connection) { 
    // do some more stuff
}

这似乎是合法的,但同时在某种程度上削弱了概念:如果 CustomStreamLikeThing 获取可关闭资源,则它们可能不会被释放。

是否有关于 AutoCloseable 的构造函数何时应该包含在 try(...) 中的指南,或者这是一个品味问题(如“包含所有我认为可能引发异常的东西")?

最佳答案

如果可以,您应该始终使用try-with-resources

当您分配资源时,您应该确保资源总是在您用完后释放。 “始终”通常意味着您应该使用 try-finally,这样在分配资源后发生的任何错误都不会阻止资源被释放。

这意味着如果你不使用try-with-resources,你需要使用try-finally,所以为什么我说总是使用try-有资源吗?

因为调用 close() 也可能会失败,而 try-with-resources 会为您处理,并在 try-with-resources 时添加了一个功能 被添加,称为抑制异常

如果您曾经在失败的 close() 调用的堆栈跟踪中诅咒,您就会知道这一点的重要性,它已经取代了本应在try-with-resources block ,因此您现在不知道真正导致问题的原因。

抑制异常 是一个经常被忽视的特性,但在 close 方法抛出级联异常时,它可以节省大量时间。就此而言,始终使用try-with-resources

附带好处:Try-with-resources 比使用 try-finally 代码更少,您应该绝对使用这两者之一处理资源时。

关于java - (何时)try-with 是否应该包含 AutoCloseable 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63793265/

相关文章:

python - `try ... except not` 施工

java - 从 try 资源结构返回 Future

java - 从两次选择器中获取总小时数

java - Java语言如何实现倒序输出?

java - 在 JodaTime 中将日期转换为其他格式

java - 通过 Java 查找系统 RAM

java - 如何在 Swing 中绘制该图?

java - 如何避免DefaultMessageListenerContainer自动启动?

javascript - Async/Await 区分拒绝和错误

具有已处理异常的 Android ACRA