AutoCloseable接口。
AutoCloseable接口非常簡單,只定義了一個close方法:
public interface AutoCloseable {
void close() Exception;
}
該接口是JDK 1.7 才新增的一個接口,方法文檔注釋該方法在try-with-resources語句中會被自動調用,用於自動釋放資源。
try-with-resources語句是JDK 1.7中一個新的異常處理機制,更方便簡潔的關閉在try-catch語句塊中使用的資源,這裡不得不提及傳統的資源釋放方式try-catch-finally:
byte[] b = new byte[1024];
FileInputStream fis = null;
try {
fis = new FileInputStream("my.txt");
int data = fis.read();
while(data != -1) {
data = fis.read(b);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println(new String(b));
傳統的資源釋放方式是利用finally語句塊的特性,不管try語句塊裡是否拋出異常,finally語句塊均會被執行,該方式存在一個較隱蔽的問題,先看下面的改造示例:
byte[] b = new byte[1024];
FileInputStream fis = null;
try {
fis = new FileInputStream("my.txt");
int data = fis.read();
while (data != -1) {
data = fis.read(b);
}
throw new RuntimeException();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
throw new RuntimeException();
} finally {
if (fis != null) {
try {
fis.close();
throw new IOException();
} catch (IOException e) {
throw new IOException();
}
}
}
System.out.println(new String(b));
本意是想捕獲RuntimeException的,但是因為finally語句塊的特性,拋出的IOException「抑制」了RuntimeException,外界捕獲到的是IOException,不便於準確的判斷問題所在。因為是根據調用棧向外拋出異常。
如果採用try-with-resources結構:
byte[] b = new byte[1024];
try(FileInputStream fis = new FileInputStream("my.txt")) {
int data = fis.read();
while (data != -1) {
data = fis.read(b);
}
}
System.out.println(new String(b));
代碼非常簡潔,而且FileInputStream資源會被自動關閉,且若拋出異常也是內部的確定異常。
byte[] b = new byte[1024];
try (FileInputStream fis = new FileInputStream("my.txt")) {
int data = fis.read();
while (data != -1) {
data = fis.read(b);
}
throw new RuntimeException();
}
當try-with-resources結構中拋出一個異常,同時fis被釋放時也拋出一個異常,最終向外拋出是try-with-resources內部的異常,反而FileInputStream資源釋放時的異常被抑制,剛好和try-catch-finally相反
若在try-with-resources結構中有多個資源需要被釋放,只要實現了AutoCloseable接口,均能被自動關閉:
byte[] b = new byte[1024];
try(
FileInputStream fis = new FileInputStream("my.txt");
BufferedInputStream bis = new BufferedInputStream(fis);
) {
int data = bis.read();
while (data != -1) {
data = fis.read(b);
}
}
System.out.println(new String(b));
關閉的順序是創建的順序的逆序。
Closeable接口繼承了AutoCloseable接口,故原有實現Closeable接口的類,均能在try-with-resources結構中使用。
也可以將自定義的類實現AutoCloseable接口,然後在try-with-resources結構中使用。