java7资源释放新语法

来源:互联网 发布:java读取xlsx文件内容 编辑:程序博客网 时间:2024/05/22 01:44

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."<init>":(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等,所以基本上可以放心的使用,就算没实现,编译器也会快速报错。

0 0
原创粉丝点击