JDK 8 try-with-resource的问题

JDK 7 中支持try-with-resource,对其中资源进行自动关闭,一直没用过,欲学习下,以便简化代码,查看文章1,文章中有说到:因为编译时编译器会自动帮代码加上finally并调用close方法(前提是这些资源类都实现了Closeable接口)。(将你编译好的.class文件拖入idea即可看到编译后的代码(idea可以反编译出来))

简单列一下书写格式:

try(资源定义){       // 在try后增加括号,括号中new资源对象
   业务逻辑            // 业务逻辑代码中也可以创建资源对象,这样也能自动关闭
} 

但在JDK8中写例子时遇到一个奇怪问题,测试例子源码如下

public class TestARM {

    public static void main(String[] args){

        test();
        System.out.println("test"); 
    }
    
    public static void test() {
                
        try (FileOutputStream out = new FileOutputStream(new File("D:/jdk8.txt"))) {
            
            @SuppressWarnings("resource")
            FileInputStream in = new FileInputStream(new File("D:/jdk8.txt"));
            
            in.available();
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

}

编译后的效果:

public class TestARM
{
  public static void main(String[] args)
  {
    test();
    System.out.println("test");
  }
  
  public static void test()
  {
    try
    {
      Object localObject1 = null;Object localObject4 = null;
      Object localObject3;
      label85:
      try
      {
        out = new FileOutputStream(new File("D:/jdk8.txt"));        
      }
      finally
      {
        FileOutputStream out;        // 为什么out变量的声明在初始化之后?
        FileInputStream in;
        localObject3 = localThrowable;
        break label85;   
        if (localObject3 != localThrowable) {
          localObject3.addSuppressed(localThrowable);
        }
      }
    }
    catch (FileNotFoundException e)
    {
      e.printStackTrace();
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }
}

并没有显示的表现在finally中有关闭in和out的代码,try-with-resource没有得到显示。并没有如文章1所说。

另外在另一篇文章中文章2又说到:try-with-resources 是 JDK 7 中一个新的异常处理机制,它能够很容易地关闭在 try-catch 语句块中使用的资源。所谓的资源(resource)是指在程序完成后,必须关闭的对象。try-with-resources 语句确保了每个资源在语句结束时关闭。所有实现了 java.lang.AutoCloseable 接口(其中,它包括实现了 java.io.Closeable 的所有对象),可以使用作为资源。

是只能关闭实现了AutoCloseable 接口的吗?

为此写下测试例子:
资源类ResourceClass:

public class ResourceClass implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("Close ResourceClasss");
        
    }
}

主类:

public class TestARM2 {

    /**
     * @param args
     */
    public static void main(String[] args) {

        test();
    }

    public static void test() {
        
        try (ResourceClass resource = new ResourceClass()) {
            
            System.out.println("resource created");
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        
    }

}

运行结果:

resource created
Close ResourceClasss

可以看到实现了AutoCloseable接口的资源被自动关闭了,那么查看下这两个类的反编译结果:
资源类ResourceClass:

public class ResourceClass

      implements AutoCloseable
    {
      public void close()
        throws Exception
      {
        System.out.println("Close ResourceClasss");
      }
    }

主类:

public class TestARM2
{
  public static void main(String[] args) {}
  
  public static void test()
  {
    try
    {
      Object localObject1 = null;Object localObject4 = null;
      Object localObject3;
      label62:
      try
      {
        resource = new ResourceClass();
      }
      finally
      {
        ResourceClass resource;
        localObject3 = localThrowable;
        break label62;
        if (localObject3 != localThrowable) {
          localObject3.addSuppressed(localThrowable);
        }
      }
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }
}

依然没有文章1中所说的添加到将close方法添加至finally块中。

记录下,如果哪位同学有答案,请赐教,谢谢

建议使用try-with-resource时配合AutoCloseable接口封装资源

猜你喜欢

转载自blog.csdn.net/qq_36101933/article/details/83268772