解決多個io流需要關閉而重複巢狀try-catch-finally的問題
阿新 • • 發佈:2019-01-10
問題如圖:
相信大多數人都見過如此狀態,流多了需要層層關閉,需要層層加上try-catch,為保證下一個流能關閉又要加上finally,煩人!!
我們先來一個測試:
public class Test { public static void main(String[] args) { try { System.out.println("第一try"); throw new Exception("異常"); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("finally"); try { throw new Exception("又是異常"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("會執行嗎"); } } }
執行結果:
提取出重要資訊,finally裡面可以抓到異常後可以繼續往下執行,也就是說finally裡面try-catch抓到異常後也必須把這個程式碼塊執行完。
那麼有人就寫了一個工具類,這種工具類對嗎?
public class IOUtil { public static void close(Closeable... closeableList) { try { for (Closeable closeable : closeableList) { if (closeable != null){ closeable.close(); } } } catch (IOException e) { e.printStackTrace(); } } }
然後
finally{
IOUtil.close(is, os);
}
看似正確,實則錯誤!!
如果第一個流關閉的時候異常,那麼第二個流close()就不可達,執行不到
這和並列寫沒區別,如下:
finally{
try{
is.close();
os.close(); // 第一個流關閉出異常第二個流關閉就不可達,執行不到,等於沒關
} catch(Exception e) {
}
}
那怎麼辦呢?不能寫工具類嗎?
不是不能寫,而是這種寫法是錯誤的,這種情況下應該把try-catch放在for迴圈裡面
正確寫法1:
public static void close(Closeable... closeableList) {
for (Closeable closeable : closeableList) {
try {
if (closeable != null) {
closeable.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
然後
finally{
IOUtil.close(is, os);
}
正確解法2:
public <T extends java.io.Closeable> void close(T t) {
try {
if (t != null) {
t.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
然後
finally {
close(in);
close(raf);
close(br);
}
哪怕其中有流關閉出了異常,也不會影響到其他流的關閉,finally{...}裡面的東西是要執行完的
=============================Talk is cheap, show me the code===========================