Java Try-With-Resources辩论

时间:2016-04-26 16:42:51

标签: java exception exception-handling try-with-resources

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

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

起初我接受了他的话,因为我是初级开发者和他的大四学生,我是新人,等等。但我最近发现嘿,所有的信息都使它成为现实进入堆栈跟踪,包括被抑制的异常。所以没有信息丢失。

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

好奇。非常感谢。

1 个答案:

答案 0 :(得分:9)

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

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

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

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

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

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

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

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