尝试使用资源详细信息 [英] try-with-resources details

查看:83
本文介绍了尝试使用资源详细信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Working with objects we use 3 basic steps:


  1. 声明

  2. 实例化

  3. 初始化

我的问题是在中必须完成哪些步骤( ) try-with的一部分,以便自动关闭资源。

And my question is about what steps must be done in () part of try-with in order auto close on resource to be made.

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

Example 1 - will FileReader object be auto closed in this code:

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

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

Example 2 - will the buf2 be auto closed in this code:

private static BufferedReader buf1;

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

    } 
 }

PS有人认为这个问题与尝试使用资源vs Try-Catch 重复。它不是。这个问题是关于try-catch和try-with-resources之间的区别。我的问题是关于try-with的细节。

P.S. Someone supposes that this question is duplicate of Try With Resources vs Try-Catch . It is not. That question is about difference between try-catch and try-with-resources. My question is about details of try-with.

推荐答案

每当需要与语言相关的细节时,最完整的参考是Java语言规格(只是谷歌)。对于尝试 -with-resources语句,您可以阅读第14.20.3节,其中说明以下内容:

Whenever language related details are needed, the most complete reference is the Java Language Specification (just Google it). For the try-with-resources statement, you can read section 14.20.3 which states that the following:

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();
            }
         }
     }
}

In你的第一个例子,资源 R BufferedReader 标识符 br 表达式 new BufferedReader(new FileReader(filePath))。因此,只有 BufferedReader 在隐式 finally 块中关闭。 finally 块不会在 FileReader 上调用 close ,因为它是资源声明本身的一部分。 然而,碰巧执行 BufferedReader.close()在内部调用关闭包装的 FileReader 的方法。所以第一个问题的答案是肯定的,因为包装器对象关闭它(遵循资源应该在自身释放时释放任何包装资源的常识),因为尝试 -with-resources。

In your first example, the resource R is BufferedReader, the Identifier is br and the Expression is new BufferedReader(new FileReader(filePath)). It follows that only the BufferedReader is closed in the implicit finally block. The finally block will not call close on the FileReader because it is not part of the resource declaration itself. However, it happens that the implementation of BufferedReader.close() internally calls the close method of the wrapped FileReader. So the answer to the first question is yes simply because the wrapper object closed it (following the common wisdom that a resource should release any wrapped resource when being itself released), not because of the try-with-resources.

在第二个例子中:

private static BufferedReader buf1;

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

    } 
}

答案取决于某些代码。这里 buf2 buf1 都指向内存中的同一个对象。如果这个某些代码将 buf1 初始化为某个对象,则该对象将被关闭,因为 buf2 也引用它。如果没有并且 buf1 为空(因此 buf2 为空),则由于空检查不会关闭任何内容在上面显示的隐式 finally 中。

the answer depends on the some code. Here buf2 and buf1 both refer to the same object in memory. If this "some code" initializes buf1 to some object, then this object will be closed since buf2 also refers to it. If not and buf1 is null (and therefore buf2 is null), then nothing will be closed because of the null check in the implicit finally shown above.

这篇关于尝试使用资源详细信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆