先了解幾個背景知識
- 什么是語法糖
- 語法糖是在語言中增加的某種語法,在不影響功能的情況下為程序員提供更方便的使用方式。
- 什么是資源
- 使用之后需要釋放或者回收的都可以稱為資源,比如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(); } }
