尝试资源详细信息[重复]

Posted

技术标签:

【中文标题】尝试资源详细信息[重复]【英文标题】:try-with-resources details [duplicate] 【发布时间】:2015-09-06 11:27:09 【问题描述】:

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

    声明 实例化 初始化

我的问题是关于在 () 部分的 try-with 中必须执行哪些步骤才能自动关闭要制作的资源。

示例 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)
    

     
 

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

【问题讨论】:

听起来像是一道作业题,但这里有一个提示:try-with-resources 要求声明的变量实现AutoCloseable,并隐式调用close()终于阻塞了。 准备(学习)认证功课。谷歌搜索 OCPJP 甚至会链接到“甲骨文大学”网站。 --- 也许The try-with-resources Statement 上的 Java 教程的第一段会对你有所帮助。 如果你真的很想学习 Java,你不应该害怕尝试。创建一个 AutoCloseable 类。在 close() 方法中添加 System.out.println 语句。将上述代码与该类一起使用,而不是 BufferedReader。看看有没有打印出来。或者只是在 BufferedReader.close() 中添加一个调试器断点,看看是否到达。 @JB Nizet 感谢您抽出宝贵时间。我不害怕。问题是我更喜欢理解原则而不是任何情况。我写在这里是因为我希望有人能给出自动关闭的主要原则。 【参考方案1】:

只要需要语言相关的详细信息,最完整的参考就是 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 块不会在 FileReader 上调用 close,因为它不是资源声明本身的一部分。 然而BufferedReader.close() 的实现会在内部调用包装好的FileReaderclose 方法。所以第一个问题的答案是肯定的,因为包装对象关闭了它(遵循资源在释放自身时应该释放任何包装资源的常识),不是因为try-有资源。

在第二个例子中:

private static BufferedReader buf1;

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

     

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

【讨论】:

【参考方案2】:

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

    try (X x = new X(new Foo())) 
    
    
    

Foo 会被关闭吗?它甚至没有实现AutoCloseable

    我写了以下代码来测试这个:

    BufferedReader buf1 = null;
    try (BufferedReader buf2 = buf1) 
    
    
    

而且它工作得非常好,没有例外!我的猜测是,在 try 语句的末尾,它会检查对象是否为空。如果不是,则关闭它。所以在这种情况下,由于 buf2 为 null,所以无法关闭。

【讨论】:

以上是关于尝试资源详细信息[重复]的主要内容,如果未能解决你的问题,请参考以下文章

防止剑道详细信息模板中的重复

异步 - 等待 JavaScript:无法从错误对象中捕获错误详细信息 [重复]

为php mail()函数设置SMTP详细信息[重复]

使用未经检查或不安全的操作,使用 -Xlint 重新编译:未检查详细信息 [重复]

使用 JAVA API 获取我的 Azure 订阅中所有资源的详细信息

如何显示“对象资源管理器详细信息”页