簡介
在Java開發中,程式員經常會遇到各種資源的釋放問題。比如最常見的I/O操作,我們往往會通過調用API提供的close方法來關閉流,釋放資源。但是追求極緻的程式員會發現,這種方式存在不少問題,比如忘記關閉流、代碼不美觀、異常不好處理等等。
今天我們就來盤一盤這個問題,最後優雅的去解決掉它。

正文
我們先來看一段代碼,大家看看自己有沒有中招,順帶認真分析一下這段代碼有什麼問題!
/**
* 讀取指定路徑檔案第一行資料内容
*
* @param path 檔案路徑
* @return
*/
public static String readFirstLine(String path){
BufferedReader br = null;
String line = null;
try {
br = new BufferedReader(new FileReader(path));
line = br.readLine();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return line;
}
這段代碼實作了一個非常簡單的功能,但是為了正确的處理異常,釋放資源,導緻代碼編寫得十分臃腫,可讀性非常的差!
那我們應該如何優化代碼呢?
最好的辦法就是采用Java 7引入的try-with-resources語句來解決,當然能使用try-with-resource的資源類,必須實作了AutoCloseable接口,比如我們Demo中的BufferedReader類,它的類關系圖如下所示:
try-with-resources使用非常友善,優化後的代碼如下所示:
* 讀取指定路徑檔案第一行資料内容 采用 try-with-resources
public static String readFirstLine(String path) {
try (BufferedReader br = new BufferedReader(new FileReader(path))){
可以看到優化後的代碼變得非常清晰,而且不需要手動寫代碼去釋放資源,這樣我們就不需要擔心資源的關閉問題了!
讀到這裡有些小夥伴肯定會想,我就是不用try-with-resources,我覺得自己釋放才靠譜。這……我隻能說你赢了,那有沒有一種稍微優雅一點的方式來釋放資源呢?
* 釋放資源,需注意資源釋放順序
* @param closeables
public static void close(Closeable... closeables) {
if (Objects.nonNull(closeables)) {
for (Closeable closeable : closeables) {
if (Objects.nonNull(closeable)) {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
我們可以考慮抽取一個方法來釋放資源,方法參數是一個可變Closeable參數,我們在手動釋放資源的時候一定要注意資源的釋放順序,是以調用方法是參數的順序一定不能錯了!
是以呀,想來想去還是try-with-resources文法香!!!