09.Guava Closer

一、背景

JDK8之前關閉資源

BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) br.close();
    }

JDK8中關閉資源

try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }

二、以上兩種方式依然存在問題

http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

try...catch...塊中如果出現異常,在執行finally過程中如果還出現異常,會影響原異常的拋出,此種現象叫做異常壓制。

三、Guava Closer

解決上述問題,使得原始異常不被壓制、影響分析問題

package com.mzj.guava.io.closer;

import com.google.common.io.Closer;
import org.junit.Test;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class CloserTest {

    /**
     * Guava Closer解決異常被壓制問題:好處是:不會漏掉異常、影響分析問題
     *
     * 此方法僅僅用於演示,不能運行,main方法中代碼可以運行
     *
     * @param args
     * @throws IOException
     */
    @Test
    public void test(String[] args) throws IOException {

        Closer closer = Closer.create();
        try {
            //將Closeable註冊到Closer中,讓其幫我們close
            BufferedReader br = closer.register(new BufferedReader(new FileReader("E:\\01.study\\03.google guava\\wamgwenjun\\other\\googleguava\\src\\main\\resources\\io\\source.txt")));
            br.readLine();
        } catch (IOException e) {
            throw closer.rethrow(e);//拋出原始異常
        } finally {
            closer.close();//調用register的Closeable的close();如果close過程出現異常則進行異常傳遞(追加):原始異常+finally執行異常統一封裝、全部拋出
        }
    }

    //===================下面所有代碼演示瞭如果不使用Guava Closer,異常被壓制的產生過程,如果解決(下面的解決過程就是Guava Closer實現)===================

    /**
     * 用於測試異常拋出、catch語句塊、finally語句塊執行順序
     */
    @Test(expected = RuntimeException.class)
    public void testTryCatchFinally() {
        try {
            System.out.println("work area");
            throw new IllegalArgumentException();
        } catch (Exception e) {
            System.out.println("exception area");
        } finally {
            System.out.println("finally area");
        }
    }

    /**
     * 演示try...finally...機制,如果在正常語句拋出異常後執行finally過程再拋異常就會壓制原異常的問題
     *
     * 執行:只看到異常2,異常1被壓制了。。。。
     */
//    public static void main(String[] args) {
//        try {
//            throw new RuntimeException("1");
//        } catch (Exception e) {
//            throw e;
//        } finally {
//            //模擬執行close時拋出異常
//            throw new RuntimeException("2");
//        }
//    }

    /**
     * 解決上述問題
     * <p>
     * 執行:看到1,2兩個異常
     * <p>
     * 這種方式就是Guava Closer所解決的問題
     */
    public static void main(String[] args) {
        Throwable t = null;
        try {
            throw new RuntimeException("1");
        } catch (Exception e) {
            t = e;
            throw e;
        } finally {
            RuntimeException runtimeException = new RuntimeException("2");
            runtimeException.addSuppressed(t);//異常傳遞(追加)
            throw runtimeException;
        }
    }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章