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/