天天看點

Java程式中如何正确的釋放資源

簡介

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

今天我們就來盤一盤這個問題,最後優雅的去解決掉它。

Java程式中如何正确的釋放資源

正文

我們先來看一段代碼,大家看看自己有沒有中招,順帶認真分析一下這段代碼有什麼問題!

/**

  * 讀取指定路徑檔案第一行資料内容

  *

  * @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類,它的類關系圖如下所示:

Java程式中如何正确的釋放資源

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文法香!!!

Java程式中如何正确的釋放資源