当前位置: 首页 > 知识库问答 >
问题:

Java与资源之争

许展鹏
2023-03-14

好的,现在在我的工作中,我们正在讨论使用资源进行尝试和异常抑制。

快速总结:java 7中的try-with资源消除了关闭资源的麻烦块的需要。我个人觉得这更优雅,但我有一个同事不相信。他不喜欢一个异常被抑制,并一直认为我们通过它松散信息。

起初我相信他的话,因为我是初级开发人员,他是高级开发人员,我是新来的,等等。但是我最近发现,嘿,所有的信息都进入了堆栈跟踪,包括被抑制的异常。所以那里没有信息丢失。

我正在寻找的最后一个争论(因为我提倡尝试资源)是自动关闭如何处理该异常。假设在尝试关闭资源时抛出异常,资源是否有可能保持打开状态并泄漏?最终这可能没什么大不了的,因为日志无论如何都会提醒我们注意这个问题。

只是好奇。非常感谢。

共有1个答案

贡和裕
2023-03-14

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

>

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

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

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

    如果关闭一个资源会引发异常,那么在这两种情况下您都无能为力。在JDBC中,数据库对象与数据库服务器通信,告诉它取消分配资源,如果关闭失败,这些资源将保持打开状态。(无论如何,重试通常毫无意义,因为问题通常是网络或连接发生了变化。)但服务器最终会清理这些内容,而这不在客户端代码的掌握之中。try-with-resources和旧的try-finally习惯用法在关闭资源方面做得同样好,只是用try-finally习惯用法需要更多的工作和更多的输入。

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

    但是在实践中,很少有人能容忍这种嵌套,他们会走捷径导致资源泄漏(通常连接不会关闭,因为最后一个块中的早期调用失败了)。人们还倾向于编写导致异常屏蔽的代码(在第二个要点中提到),在关闭时抛出的异常会导致在try块中抛出的异常丢失;尝试资源可以防止这种错误。尝试资源肯定有一席之地。

    我的建议是尽你所能学习异常处理,编写演示异常如何工作的示例程序,并理解这两种方法的优缺点,这样你就可以详细讨论它们,进行比较和对比。这样你就可以表明你理解同事提出的问题,你可以提供建议,而不是作为一种方法的倡导者,而是为了帮助你的团队找到帮助他们编写更好软件的解决方案

  •  类似资料:
    • 问题内容: 之间有什么区别 与 我在src / test / resources中有资源,我正在尝试从单元测试中访问它们。这是典型的maven样式目录结构。 我期望两者的行为相同。但是事实并非如此。getClass()。getResource()无法获取资源,而从Thread可以获取资源。 那么它们有何不同? 问题答案: 有一种特殊情况使第一个类运行(这就是为什么必须将main()方法声明为静态的

    • 两者之间有什么区别 VS 我在src/test/resources中有资源&我正试图从单元测试中访问它们。这是一种典型的maven风格目录结构。

    • 问题内容: 我正在编写一个连接到网站并从中读取一行的应用程序。我这样做是这样的: 好吗?我的意思是,我在最后一行关闭了BufferedReader,但没有关闭InputStreamReader。我是否应该从connection.getInputStream创建一个独立的InputStreamReader,并从独立的InputStreamReader创建一个BufferedReader,而不是关闭所

    • 22.10.资源 Java 插件使用 Copy 任务处理资源. 它为项目每个 source set 都增加了一个实例. 可以参考Section 15.6, “Copying files” 获取关于copy任务的信息. 表22.12.java 插件- ProcessResources 的属性 任务属性 类型 默认值 srcDirs Object.可以在Section 15.5, “Specifyin

    • 由于我的两个JPA实体(任务和作业)的双向关系中的嵌套循环,我出现了Jackson错误。我开始研究并使用@JsonManagedResources和@JsonBackResources注释部分解决了这个问题,但此方法仅在我在实体中使用注释时才有效,最终JSON序列化跳过我的JobResource/JobResourceAssembler和TaskResource/TaskResourceAssem

    • 来自维基百科: 要发起跨源请求,浏览器发送带有源HTTP标头的请求。这个标题的值是为页面服务的站点。例如,假设http://www.example-social-network.com上的一个页面试图访问online-personal-calendar.com中的用户数据。如果用户的浏览器实现了CORS,则将发送以下请求头: 来源:http://www.example-social-network