中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

effective java第三版推薦使用try-with-resources代替try-finally的原因是什么

發布時間:2021-10-25 16:07:21 來源:億速云 閱讀:150 作者:iii 欄目:編程語言

本篇內容主要講解“effective java第三版推薦使用try-with-resources代替try-finally的原因是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“effective java第三版推薦使用try-with-resources代替try-finally的原因是什么”吧!

背景

try-finally 這個語句想必做java的同學都不陌生吧,每當我們有關閉資源的需求我們都會使用到try-finally這個語句,比如我們在使用鎖的時候,無論是本地的可重入鎖還是分布式鎖都會有下面類似的結構代碼,我們會在finally里面進行unlock,用于強制解鎖:

    Lock lock = new ReentrantLock();
    lock.lock();
    try{
        // doSometing
    }finally {
        lock.unlock();
    }

或者我們使用java的文件流讀取或者寫入文件的時候,我們也會在finally中強制關閉文件流,防止資源泄漏。

    InputStream inputStream = new FileInputStream("file");
    try {
        System.out.println(inputStream.read(new byte[4]));
    }finally {
        inputStream.close();
    }

其實乍一看 這樣的寫法應該沒什么問題,但是如果我們出現了多個資源需要關閉我們應該怎么寫呢?最常見的寫法如下:

InputStream inputStream = new FileInputStream("file");
    OutputStream outStream = new FileOutputStream("file1");

    try {
        System.out.println(inputStream.read(new byte[4]));
        outStream.write(new byte[4]);
    }finally {
        inputStream.close();
        outStream.close();
    }

我們在外面定義了兩個資源,然后在finally里面依次對這兩個資源進行關閉,這個寫法在我最開始寫java的時候對文件流和數據庫連接池做close的時候一些教學的文章都是這么教學的,那么這個哪里有問題呢?問題其實在于如果在inputStream.close的時候拋出異常,那么outStream.close()就不會執行,這很明顯不是我們想要的結果,所以后面就改成了下面這種多重嵌套的方式去寫:

    InputStream inputStream = new FileInputStream("file");
    try {
        System.out.println(inputStream.read(new byte[4]));
        try{
            OutputStream outStream = new FileOutputStream("file1");
            outStream.write(new byte[4]);
        }finally {
            outStream.close();
        }
    }finally {
        inputStream.close();
    }

在這種方式中即便是outStream.close()拋出了異常,但是我們依然會執行到inputStream.close(),因為他們是在不同的finally塊,這個的確解決了我們的問題,但是還有兩個問題沒有解決:

  • 帶來的第一個問題就是如果我們有不止兩個資源,比如有十個資源,難道需要讓我們寫十個嵌套的語句嗎?寫完之后這個代碼還能看嗎?

  • 第二個問題就是如果我們在try里面出現異常,然后在finally里面又出現異常,就會導致異常覆蓋,會導致finally里面的異常將try的異常覆蓋了。

public class CloseTest {

    public void close(){
        throw new RuntimeException("close");
    }

    public static void main(String[] args) {
        CloseTest closeTest = new CloseTest();
        try{
            throw new RuntimeException("doSomething");
        }finally {
            closeTest.close();
        }
    }

}
輸出結果:Exception in thread "main" java.lang.RuntimeException: close

上面這個代碼,我們期望的是能拋出doSomething的這個異常,但是實際的數據結果卻是close的異常,這和我們的預期不符合。

try-with-resources

上面我們介紹了兩個問題,于是在java7中引入了try-with-resources的語句,只要我們的資源實現了AutoCloseable這個接口那么我們就可以使用這個語句了,我們之前的文件流已經實現了這個接口那么我們可以直接使用:

try(InputStream inputStream = new FileInputStream("file");
            OutputStream outStream = new FileOutputStream("file1")) {
            System.out.println(inputStream.read(new byte[4]));
            outStream.write(new byte[4]);
        }

我們所有的資源定義全部都在try后面的括號中進行定義,通過這種方式我們就可以解決上面所說的幾個問題:

  • 首先第一個問題,我們通過這樣的方式,代碼非常整潔,無論你有多少個資源,都可以很簡潔的去做。

  • 第二個異常覆蓋問題的話,我們可以通過實驗來看一下,我們將代碼改寫為如下:

public class CloseTest implements AutoCloseable {

    @Override
    public void close(){
        System.out.println("close");
        throw new RuntimeException("close");
    }

    public static void main(String[] args) {
        try(CloseTest closeTest = new CloseTest();
            CloseTest closeTest1 = new CloseTest();){
            throw new RuntimeException("Something");
        }
    }

}
輸出結果為:
close
close
Exception in thread "main" java.lang.RuntimeException: Something
	at fudao.CloseTest.main(CloseTest.java:33)
	Suppressed: java.lang.RuntimeException: close
		at fudao.CloseTest.close(CloseTest.java:26)
		at fudao.CloseTest.main(CloseTest.java:34)
	Suppressed: java.lang.RuntimeException: close
		at fudao.CloseTest.close(CloseTest.java:26)
		at fudao.CloseTest.main(CloseTest.java:34)

我們在代碼中定義了兩個CloseTest,用來驗證之前close出現異常是否會影響第二個,同時在close和try塊里面都拋出不同的異常,可以看見我們的結果,輸出了兩個close,證明雖然close拋出異常,但是兩個close都會執行。然后輸出了doSomething的異常,可以發現這里我們輸出的就是我們try塊里面所拋出的異常,并且我們close的異常以Suppressed的方式記錄在異常的堆棧里面,通過這樣的方式我們兩種異常都能記錄下來。

try-with-resources原理

try-with-resources語句其實是一種語法糖,通過編譯之后又回到了我們開始說的嵌套的那種模式: effective java第三版推薦使用try-with-resources代替try-finally的原因是什么

可以發現try-with-resources被編譯之后,又采取了嵌套的模式,但是和之前的嵌套有點不同,他close的時候都利用了catch去捕獲了異常,然后添加到我們真正的異常中,整體邏輯比我們之前的嵌套要復雜一些。

到此,相信大家對“effective java第三版推薦使用try-with-resources代替try-finally的原因是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

根河市| 荔波县| 临夏县| 六安市| 墨玉县| 虹口区| 邢台县| 咸阳市| 镇雄县| 修水县| 昌宁县| 教育| 莱州市| 宝坻区| 平乐县| 新河县| 册亨县| 井陉县| 莒南县| 沙坪坝区| 育儿| 突泉县| 固阳县| 肥城市| 上饶市| 永定县| 富阳市| 德化县| 呼伦贝尔市| 特克斯县| 玛纳斯县| 广西| 岑溪市| 兴业县| 铁力市| 柯坪县| 自贡市| 北宁市| 南召县| 霍城县| 冷水江市|