Java Try-With-Resources辩论

use*_*059 5 java exception-handling exception try-with-resources

好了,在我的工作中,我们正在讨论试用资源和异常抑制.

快速回顾:来自java 7的try-with-resources消除了对那个讨厌的finally块关闭资源的需要.我个人认为它更优雅,但我有一个不相信的同事.他不喜欢一个例外被压制,并且一直在争论我们通过它来丢失信息.

起初我接受了他的话,因为我是一个初级开发者,他是高级,我是新人,等等.但我最近发现,嘿,所有信息都进入堆栈跟踪,包括被抑制的异常.所以没有信息丢失.

我正在寻找的这场辩论的最后一部分(因为我主张尝试使用资源)是自动关闭处理异常的方式.假设在尝试关闭资源时抛出异常,资源是否可能保持打开和泄漏?最终这可能不是什么大问题,因为无论如何日志都会提醒我们这个问题.

只是好奇.非常感谢.

Nat*_*hes 9

你是正确的,抑制异常不会导致信息丢失.你的同事对此的担忧是毫无根据的.尝试资源的要点是:

  • 确保资源关闭,无论使用它们时抛出什么,并按照它们声明的相反顺序,

  • 确保关闭时抛出的异常不会导致try块中抛出的异常丢失,并且

  • 确保关闭时抛出的异常仍然保留为抑制异常,因此不会丢失任何信息.

如果关闭资源会抛出异常,那么在任何一种情况下你都无法做到.在JDBC中,数据库对象与数据库服务器进行通信,以告知它取消分配资源,如果关闭失败,它们将保持打开状态.(并且重试通常是毫无意义的,因为问题通常是网络或连接发生了变化.)但服务器最终会清理它们,而且它不在客户端代码的手中.尝试使用资源和较旧的try-finally成语同样可以很好地关闭资源,这只是更多的工作,更多的输入与try-finally成语.

对于我来说,使用try-with-resources还是嵌套的try-finally语句,最大的区别在于,在前一种情况下,如果try块中没有抛出任何内容并且某些内容被抛出,则抛出close抛出的异常(因为在try-block中没有抛出任何异常将它附加到一个被抑制的异常).如果使用嵌套的try-finally块,则可以确保关闭时抛出的异常不会从finally块传播,因此在释放资源时间歇性网络故障不会导致丢失有效的业务事务.

但实际上很少有人能够容忍这种嵌套,并且他们采用导致资源泄漏的快捷方式(通常由于finally块中的早期调用失败而无法关闭的连接).人们还倾向于编写导致异常屏蔽的代码(在第二个项目符号中提到),其中关闭时抛出的异常会导致try-block中抛出的异常丢失; try-with-resources可以防止出现这种错误.绝对有资源尝试的地方.

我的建议是学习有关异常处理的所有知识,编写演示异常如何工作的示例程序,并理解两种方法的优点和缺点,以便您可以详细讨论它们并进行比较和对比.通过这种方式,您可以证明您了解您的同事提出的问题,并且您可以提供建议,而不是作为一种方式的倡导者,而是帮助您的小组找到有助于其编写更好软件的解决方案.