java7资源释放新语法

java中关于资源的使用大家估计都不陌生,无非就是请求资源,建立连接,读取资源,关闭资源几个步骤,为了保证资源能够顺利释放,都是在finally块中进行资源释放,下面常见的资源访问实例:

    public static void main(String[] args) {
        FileInputStream fis = null;
        try {
            fis = new FileInputStream("");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if(fis != null) 
                    fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

上面的代码 ,简单的功能需要的代码长且不说,而且不够优雅,在同时有输入流输出流的情况,将会更加复杂,异常处理难度令人抓狂。
现在我们可以摆脱这种现状了,java7新语法,提供自动关闭资源的方式,如下

    public static void main(String[] args) {
        try (FileInputStream fis = new FileInputStream("");) {
            fis.read();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

仔细看,资源的连接是在try()中,这种新语法支持,凡是实现接口AutoCloseable的类都可以使用这种方式进行资源访问,并且会自动释放。
下面,我们仔细分析下,为什么资源会自动释放,我们看下面这段,是新 方式代码javap后的汇编,我简单的注释下:

 public static void main(java.lang.String[]);
    Code:
       0: aconst_null   
       1: astore_1      
       2: aconst_null   
       3: astore_2      
       4: new           #16                 // class java/io/FileInputStream
       7: dup           
       8: ldc           #18                 // String 
      10: invokespecial #20                 // Method java/io/FileInputStream."":(Ljava/lang/String;)V
      13: astore_3                          //将实例化的FileInputStream对象引入保存到局部变量3中
      14: aload_3                           //FileInputStream引用入栈
      15: invokevirtual #23                 // Method java/io/FileInputStream.read:()I
      18: pop           
      19: aload_3                            
      20: ifnull        76                   //资源为空,则表示没有开启资源,也成功返回
      23: aload_3                            //如果保存FileInputStream对象引用的变量不为空则关闭资源
      24: invokevirtual #27                 // Method java/io/FileInputStream.close:()V
      27: goto          76                  //成功返回
      30: astore_1                          //既然上面代码就能保证成功返回,此处开始的代码就是异常处理了
      31: aload_3       
      32: ifnull        39
      35: aload_3       
      36: invokevirtual #27                 // Method java/io/FileInputStream.close:()V
      39: aload_1       
      40: athrow        
      41: astore_2      
      42: aload_1       
      43: ifnonnull     51
      46: aload_2       
      47: astore_1      
      48: goto          61
      51: aload_1       
      52: aload_2       
      53: if_acmpeq     61
      56: aload_1       
      57: aload_2       
      58: invokevirtual #30                 // Method java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
      61: aload_1       
      62: athrow        
      63: astore_1      
      64: aload_1       
      65: invokevirtual #36                 // Method java/io/FileNotFoundException.printStackTrace:()V
      68: goto          76
      71: astore_1      
      72: aload_1       
      73: invokevirtual #41                 // Method java/io/IOException.printStackTrace:()V
      76: return        
    Exception table:      //这是java异常处理的机制,维护异常表,根据表来查询异常后的跳转代码。
       from    to  target type
          14    19    30   any      //当资源读时异常,跳到30处(内存偏移量)继续执行,可以看到是资源关闭的处理。
           4    41    41   any
           0    63    63   Class java/io/FileNotFoundException
           0    63    71   Class java/io/IOException

分析后发现,新的语法其实就是一种编译器优化,资源总会关闭,不管是否发生异常。人通常会犯错,但是编译器却不会,所以使用新的方式进行资源访问,能够避免隐藏的bug,而在java7中绝大多数的资源访问都已经重新实现了AutoCloseable接口,包括网络访问socket等,所以基本上可以放心的使用,就算没实现,编译器也会快速报错。

你可能感兴趣的:(java基础)