先了解几个背景知识
- 什么是语法糖
- 语法糖是在语言中增加的某种语法,在不影响功能的情况下为程序员提供更方便的使用方式。
- 什么是资源
- 使用之后需要释放或者回收的都可以称为资源,比如JDBC的connection连接,文件IO的各种类。
- 在这里我们可以简单理解为实现了 java.lang.AutoCloseable/java.io.Closeable接口的类对象。
回到正题,try-with-resources是什么?
- 是java的一个语法糖,在try语句中声明一个或者多个资源。
哪些资源可以用于try-with-resources呢?
- 实现了 java.lang.AutoCloseable/java.io.Closeable 的类对象
现在如果不用try-with-resources我需要怎么实现代码?
package testReadFile; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class ReadFile { public static void main(String[] args) { BufferedReader reader = null; String buffer = null; try { reader = new BufferedReader(new FileReader("src/testRead.txt")); do { buffer = reader.readLine(); System.out.println(buffer); } while (reader.read() != -1); } catch (IOException e) { e.printStackTrace(); } finally { try { // 问题一:需要显示的调用close,也要对close再加一层try catch 还有个问题是 // 问题二:close函数也有可能抛异常,如果这里抛出异常,try块里面的异常信息就会被丢弃 reader.close(); } catch (IOException e) { e.printStackTrace(); } } } }
使用try-with-resources的实现
package testReadFile; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class ReadFile { public static void main(String[] args) { String bufferSugar = null; try (BufferedReader readerSugar = new BufferedReader(new FileReader("src/testRead.txt"))) { bufferSugar = readerSugar.readLine(); System.out.println(bufferSugar); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
发现没,编程上简单很多。
用jad工具反编译,源码分析,try-with-resources做了什么?
简单来说,其实就是帮你做了两件事
- 添加了close
- try块里面和close函数都可能抛出异常,这里会将try块抛出的异常压缩成Suppressed Exceptions,可以调用Throwable.getSuppressed方法取出被抑制的异常
package testReadFile; import java.io.*; public class ReadFile { public ReadFile() { } public static void main(String args[]) { String bufferSugar = null; Exception exception; exception = null; Object obj = null; BufferedReader readerSugar = new BufferedReader(new FileReader("src/testRead.txt")); bufferSugar = readerSugar.readLine(); System.out.println(bufferSugar); if(readerSugar != null) readerSugar.close(); break MISSING_BLOCK_LABEL_90; exception; if(readerSugar != null) readerSugar.close(); throw exception; Exception exception1; exception1; if(exception == null) exception = exception1; else if(exception != exception1) exception.addSuppressed(exception1); throw exception; IOException e; e; e.printStackTrace(); } }