尝试使用资源详细信息

时间:2015-09-06 11:27:10

标签: java

使用对象我们使用3个基本步骤:

  1. 声明
  2. 实例化
  3. 初始化
  4. 我的问题是在()尝试的部分必须完成哪些步骤才能自动关闭资源。

    示例1 - 将在此代码中自动关闭FileReader对象:

    try (BufferedReader br = new BufferedReader(new FileReader(filePath)))
    {
    //some code;
    } 
    

    示例2 - 将在此代码中自动关闭buf2:

    private static BufferedReader buf1;
    
    public static void main(String[] args) throws IOException {
        //some code
        try (BufferedReader buf2 = buf1)
        {
    
        } 
     }
    

    P.S。有人认为这个问题与Try With Resources vs Try-Catch重复。它不是。这个问题是关于try-catch和try-with-resources之间的区别。我的问题是关于试用的细节。

2 个答案:

答案 0 :(得分:5)

每当需要与语言相关的详细信息时,最完整的参考是Java语言规范(仅限Google)。对于try - with-resources语句,您可以阅读section 14.20.3,其中包含以下内容:

try ({VariableModifier} R Identifier = Expression ...)
    Block

被翻译为

{
   final {VariableModifierNoFinal} R Identifier = Expression; 
   Throwable #primaryExc = null;
   try ResourceSpecification_tail
      Block catch (Throwable #t) {
         #primaryExc = #t;
         throw #t;
      } finally {
         if (Identifier != null) {
            if (#primaryExc != null) { 
               try { 
                  Identifier.close(); 
               } catch (Throwable #suppressedExc) { 
                  #primaryExc.addSuppressed(#suppressedExc);
               }
            } else {
               Identifier.close();
            }
         }
     }
}

在您的第一个示例中,资源RBufferedReaderIdentifierbrExpressionnew BufferedReader(new FileReader(filePath))。因此,只有BufferedReader在隐式finally块中关闭。 finally数据块不会在close上调用FileReader,因为不是资源声明本身的一部分。 ,恰好BufferedReader.close()的实施内部调用了包裹的close的{​​{1}}方法。所以第一个问题的答案是肯定的,因为包装器对象关闭它(遵循资源应该在自身释放时释放任何包装资源的常识), not 因为{{1} } -with资源。

在第二个例子中:

FileReader

答案取决于try。这里private static BufferedReader buf1; public static void main(String[] args) throws IOException { //some code try (BufferedReader buf2 = buf1) { } } some code都指向内存中的同一个对象。如果这"一些代码"将buf2初始化为某个对象,然后此对象将被关闭,因为buf1也引用它。如果不是,并且buf1为空(因此buf2为空),则由于上面显示的隐式buf1中的空检查,所以不会关闭任何内容。

答案 1 :(得分:1)

  1. FileReader将被关闭。但那不是因为它在try语句中。这是因为当BufferedReader关闭时,它也会在close()上调用FileReader。对于一个反例,我有一个名为X的类,它实现了AutoCloseable。该类在其构造函数中需要一个Foo对象。所以我写道:

    try (X x = new X(new Foo())) {
    
    }
    
  2. Foo会被关闭吗?它甚至没有实现AutoCloseable

    1. 我写了以下内容来测试这个:

      BufferedReader buf1 = null;
      try (BufferedReader buf2 = buf1) {
      
      }
      
    2. 它工作得很好,没有例外!我的猜测是,在try语句的末尾,它检查对象是否为null。如果不是,则关闭它。所以在这种情况下,因为buf2为空,所以它不能被关闭。