天天看點

第9 條: try-with-resources 優先于try-finallytry-with-resources 優先于try-finally

try-with-resources 優先于try-finally

我們一般在關閉資源的時候都會選用try-finally,比如關閉各種讀寫流,資料庫連接配接對象等,都會在finally中調用對象的close方法,即使發生異常也會確定資源被釋放,這看上去沒有什麼問題。

但是再添加另一個資源,就會顯的亂七八糟的感覺,如下是檔案拷貝代碼示例。

public static void copy(String src,String dst) throws IOException {
        InputStream in = new FileInputStream(src);
        try {
            OutputStream out = new FileOutputStream(dst);
            try {
                byte[] buf = new byte[1024];
                int n;
                while ((n = in.read(buf)) >= 0) {
                    out.write(buf,0,n);
                }
            } finally {
                out.close();
            }
        } finally {
            in.close();
        }
    }在這裡插入代碼片
           

在上面的代碼示例中有兩個缺點

1.關閉的資源多了,try-finally就嵌套的多了,代碼感覺很亂。

2.try和finally中都會抛出異常,如果底層實體裝置異常,那麼try中流在讀檔案的過程中就會有異常,同樣finally中流close的時候也會發生異常,這種情況下,close中的異常就會覆寫try中的異常,try中的異常甚至都沒有列印出錯誤堆棧,顯然try中的異常才是對我們有價值的異常。

是以為了避免上述的問題,我們應該使用java7中引用的try-with-resource語句,上面的兩個問題就不會存在了,要關閉資源的類必須實作AutoCloseable接口,包含無傳回值的close方法,現在java中的很多類庫都實作了這個接口。

public static void copy(String src, String dst) throws IOException {

        try (InputStream in = new FileInputStream(src);
             OutputStream out = new FileOutputStream(dst);) {
            byte[] buf = new byte[1024];
            int n;
            while ((n = in.read(buf)) >= 0) {
                out.write(buf, 0, n);
            }
        }
    }
           

現在第一個代碼就變成了這樣,将要關閉的資源放在了try後面的括号裡面,自己就會在用完的時候釋放資源,而且如果發生異常也是會列印出第一個異常,close裡面的異常就會被禁止,我們就可以找到對我們有用的異常。

結論

結論很明顯: 在處理必須關閉的資源時,始終要優先考慮用try- with-resources ,而不是

用try-finally 。這樣得到的代碼将更加簡潔、清晰,産生的異常也更有價值。有了trywith-

resources 語句,在使用必須關閉的資源時,就能更輕松地正确編寫代碼了。實踐證明,

這個用try-finally 是不可能做到的。

繼續閱讀