简体   繁体   English

Java试用资源辩论

[英]Java Try-With-Resources Debate

Ok now, at my job we're having a debate over try-with-resources and exception suppression. 好的,现在,在我的工作中,我们正在就尝试资源和异常抑制进行辩论。

Quick recap: try-with-resources, from java 7, eliminates the need for that pesky finally block to close resources. 快速回顾:来自Java 7的try-with-resources消除了对讨厌的final块关闭资源的需求。 I personally feel it is way more elegant, but I have a coworker who isn't convinced. 我个人觉得它更优雅,但是我有一个不相信的同事。 He doesn't like that the one exception gets suppressed, and has been arguing that we loose information through that. 他不喜欢抑制一个例外,并且一直在争论我们通过那个例外来释放信息。

At first I was taking his word for it, because I'm a junior dev and he's senior, I'm new, etc. But I recently discovered that hey, all the info makes it into the stack trace, including the suppressed exception. 起初,我是听他的话的,因为我是一个初级开发人员,他是高级,我是新手,等等。但是我最近发现,嘿,所有信息都将其放入堆栈跟踪,包括被抑制的异常。 So no information is lost there. 因此,那里没有任何信息丢失。

The last piece of this debate that I'm looking for (since I'm advocating for try-with-resources) is how auto-closeable handles that exception. 我正在寻找的辩论的最后一部分(因为我主张使用try-with-resources)是自动关闭如何处理该异常。 Let's say an exception is thrown while trying to close a resource, is there the potential that resource could stay open and leak? 假设在尝试关闭资源时抛出了异常,是否有可能资源保持打开和泄漏的可能性? Ultimately this may not be such a big deal, since the logs would alert us to this issue anyway. 最终,这可能没什么大不了的,因为无论如何日志都会提醒我们注意此问题。

Just curious. 只是好奇。 Thanks so much. 非常感谢。

You are correct that suppressing the exception does not result in losing information. 您是正确的,抑制异常不会导致信息丢失。 Your co-worker's concern about that is groundless. 您的同事对此的担忧是没有根据的。 The points of try-with-resources are: 尝试资源的要点是:

  • to make sure that resources get closed, regardless of what is thrown while using them, and in the reverse order in which they're declared, 以确保关闭资源,无论使用它们时抛出了什么,并以声明它们的相反顺序,

  • to make sure that exceptions thrown on close don't cause exceptions thrown in the try block to get lost, and 确保关闭时抛出的异常不会导致try块中抛出的异常丢失,并且

  • to make sure that exceptions thrown on close still get retained as suppressed exceptions so no information is lost. 确保在关闭时抛出的异常仍保留为抑制的异常,因此不会丢失任何信息。

If closing a resource throws an exception, there's nothing you can do about it in either case. 如果关闭资源引发异常,则在任何一种情况下您都无能为力。 In JDBC the database objects communicate back to the database server to tell it to de-allocate resources, and those would stay open if close fails. 在JDBC中,数据库对象传回数据库服务器以告诉它取消分配资源,如果关闭失败,它们将保持打开状态。 (And retrying is usually pointless anyway because the problem is typically that something changed about the network or the connection.) But the server will clean those up eventually, and it's out of the client code's hands. (无论如何,重试通常是没有意义的,因为问题通常是网络或连接发生了变化。)但是服务器最终将清理掉这些内容,这不在客户端代码的控制范围之内。 Both try-with-resources and the older try-finally idiom do an equally good job of closing resources, it's just more work and more typing with the try-finally idiom. 使用资源的尝试方法和较旧的尝试-最终习惯用法在关闭资源方面都做得同样好,尝试-最终习惯用语的工作量更大,打字也更多。

The biggest difference to me in whether to use try-with-resources or nested try-finally statements is that in the former case, if nothing is thrown in the try block and something is thrown on close, the exception thrown on close is thrown (since there's no exception thrown in the try-block to attach it to as a suppressed exception). 对于我而言,无论是使用try-with-resources还是嵌套的try-finally语句,最大的区别在于,在前一种情况下,如果try块中没有抛出任何异常,并且在close上抛出了异常,则在close上抛出了异常(因为在try块中没有抛出任何异常以将其附加为受抑制的异常)。 If you use nested try-finally blocks then you can make sure exceptions thrown on close do not propagate from the finally block, so that an intermittent network glitch while releasing resources doesn't result in losing a valid business transaction. 如果使用嵌套的try-finally块,则可以确保在close块上抛出的异常不会从finally块传播,这样在释放资源时出现间歇性网络故障不会导致丢失有效的业务交易。

But in practice very few people have the tolerance for this kind of nesting and they take shortcuts that lead to resource leaks (typically connections that don't get closed because an earlier call in the finally block failed). 但是在实践中,很少有人能容忍这种嵌套,并且他们采取了导致资源泄漏的捷径(通常,由于在finally块中的较早调用失败而导致连接无法关闭)。 People also tend to write code that causes exception-masking (mentioned in the second bullet point), where the exception thrown on close causes an exception thrown within the try-block to be lost; 人们还倾向于编写导致异常屏蔽的代码(在第二个要点中提到),其中抛出在关闭状态的异常会导致在try块内抛出的异常丢失。 try-with-resources prevents this kind of error. try-with-resources可以防止这种错误。 There is definitely a place for try-with-resources. 绝对有一个尝试资源的地方。

My advice is to learn all you can about exception handling, write example programs demonstrating how exceptions work, and understand the strong and weak points of both approaches so that you can talk about them in detail and compare and contrast. 我的建议是学习有关异常处理的所有知识,编写示例程序演示异常的工作方式,并了解两种方法的优缺点,以便您可以详细讨论它们以及进行比较和对比。 That way you can show that you understand the concerns your co-workers raise and you can give advice not as an advocate for one way over the other but with a goal of helping your group find solutions that help it write better software. 这样,您可以表明自己了解同事提出的问题,并且可以提供建议,而不是作为一种倡导者来代替另一种方法,而是旨在帮助您的小组找到有助于其编写更好软件的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM