try-with-resource关闭序列:FileInputStream关闭执行三次

时间:2015-06-02 18:56:20

标签: java debugging java-7 try-with-resources

我在OS X上尝试使用Java 8的简单try-with-resource示例。 我看到一些奇怪的行为。首先,以下是我正在运行的代码:

 public void test() {

        try( FileInputStream fin = new FileInputStream("/tmp/test");
             FileOutputStream fout = new FileOutputStream("/tmp/test1")
                ){

            System.out.println("Nothing here");
            System.out.println("Nothing here");
        }catch (Exception e) {
            System.err.println("Error "  + e);
        }
    }

应用程序运行正常并按预期打印Nothing here两次。 当我在调试模式(IntelliJ构思)中运行时,执行在FileInputSteam::close()暂停两次,然后在FileOutputStream::close()暂停,然后再次在FileInputStream::close()暂停 - 要检查此行为的来源,我通过jad-gui查看了.class文件。它显示以下代码:

public void test()
  {
    try
    {
      FileInputStream fin = new FileInputStream("/tmp/test");Throwable localThrowable6 = null;
      try
      {
        FileOutputStream fout = new FileOutputStream("/tmp/test1");Throwable localThrowable7 = null;
        try
        {
          System.out.println("Nothing here");
          System.out.println("Nothing here");
        }
        catch (Throwable localThrowable1)
        {
          localThrowable7 = localThrowable1;throw localThrowable1;
        }
        finally {}
      }
      catch (Throwable localThrowable4)
      {
        localThrowable6 = localThrowable4;throw localThrowable4;
      }
      finally
      {
        if (fin != null) {
          if (localThrowable6 != null) {
            try
            {
              fin.close();
            }
            catch (Throwable localThrowable5)
            {
              localThrowable6.addSuppressed(localThrowable5);
            }
          } else {
            fin.close();
          }
        }
      }
    }
    catch (Exception e)
    {
      System.err.println("Error " + e);
    }
  }

这更令人困惑。

为什么反编译代码不会显示对 FileOutputStream::close()的任何调用 - 这是jd-gui的问题吗?

为什么在调试期间控件首先进行两次 FileInputStream::close()?这是一些错误还是它应该如何工作?

1 个答案:

答案 0 :(得分:1)

请参阅@ jb-nizet的评论你的反编译器没有显示正确的内容,这解释了你的问题1.

对于问题2,请查看调试器中的Stream.path变量。在我的系统上,这不是您的Streams开放,而是Java 8内部文件,如" /opt/Oracle_Java/jdk1.8.0_40/jre/lib/tzdb.dat" ;," / opt / Oracle_Java /jdk1.8.0_40/jre/lib/meta-index"和班级本身。但我只有一次调用InputStream" / tmp / test"一个用于输出流" / tmp / test1"。