有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

当声明多个最终资源时,java trywithresource是否不安全?

由于Java 9,我们可以在try with resources中有效地使用final变量

下面的示例显示了一种情况,其中一个资源初始化引发异常

    public static void main(String[] args) {
        Resource1 r1 = new Resource1();
        Resource2 r2 = new Resource2(); // exception will be thrown
        try (r1; r2) {
            System.out.println("TryWithResources.main() try");
        } catch (Exception e) {
            System.out.println("TryWithResources.main() catch");
        }
    }
    
    static class Resource1 implements AutoCloseable {
        @Override
        public void close() throws Exception {
            System.out.println("TryWithResources.Resource1.close()");
        }
    }
    
    static class Resource2 implements AutoCloseable {
        public Resource2() {
            throw new RuntimeException();
        }
        @Override
        public void close() throws Exception {
            System.out.println("TryWithResources.Resource2.close()");
        }
    }

当我运行这个示例时,我得到的唯一输出是RuntimeException,这意味着Resource1没有关闭。这是意料之中的,因为它没有在try with resources中初始化

但是,这是预期的结果,还是我遗漏了什么

因为,如果这实际上是它应该工作的方式,那么在我看来,这种新语法实际上消除了许多最初由try with resources语句带来的安全性

有人能确认一下情况是否属实吗? 如果是肯定的,我们为什么要在多个资源中使用这种语法并承担风险呢


共 (1) 个答案

  1. # 1 楼答案

    为了使try-with-resources机制工作,您应该将初始化代码放入try。您的初始化似乎发生在前一行。如果你愿意:

      public static void main(String[] args) {
        try (Resource1 r1 = new Resource1(); Resource2 r2 = new Resource2()) {
          System.out.println("TryWithResources.main() try");
        } catch (Exception e) {
          System.out.println("TryWithResources.main() catch");
        }
      }
    

    这将打印:

    TryWithResources.Resource1.close()
    TryWithResources.main() catch
    

    所以你的代码应该是这样读的:“我想自动关闭r1r2,但我更喜欢自己初始化它”

    我的版本应该是这样的:“我想自动关闭r1r2,并且我想将其初始化为try块的一部分”