1. 程式人生 > >Try-Catch-Finally代碼塊中的return

Try-Catch-Finally代碼塊中的return

打印 代碼 style pri bsp 自己 println public row

測試類的原型是這樣子的

public class TryCatchFinallyToReturn {

    public static void main(String[] args) {
        System.out.println(test());
    }

    public static int test() {
        try {
            System.out.println("try block.");
            throwMethod();
            return 1;
        } catch(Exception e) {
            System.out.println(
"catch block."); return 2; } finally { System.out.println("finally"); return 3; } } public static void throwMethod() throws Exception { } }

可以看到finally代碼塊整個大括號都出現了警告了,

finally block does not complete normally

說明finally{}中出現return是不合適的。

強行運行一下,結果是這樣的(結果1

try block.
finally block.
3

通過斷點追蹤,try{}中的return 1已經運行到了,但是try{}正常運行結束後,finally{}必須要被執行

最後所以真正的返回值是3

變更一下測試原型,測試一下出現異常的情況

    public static void throwMethod() throws Exception {
        System.out.println("throw.");
        throw new Exception();
    }

運行一下(結果2

try block.
throw.
catch block.
finally block.
3

異常被捕獲到了catch{}中的return 2確保了運行,但是返回值依然是finall{}中的return 3。

同樣的,通過斷點追蹤發現return 2也被運行到了,但是被return 3覆蓋

最後刪除finally{} 中的return 3

        } finally {
            System.out.println("finally block.");
        }

運行一下通過調整throwMethod方法,分別測試一下正常情況和異常情況(結果3)(結果4

try block.
finally block.
1
try block.
throw.
catch block.
finally block.
2

返回值正確了。

現在可以得到4個結論

A、運行時發生異常的那條語句再也沒有機會運行到了,原因是異常被catch()捕獲到,程序流程進入了catch{}

這點可以通過結果2看到,斷點沒有運行到return 1

B、無論try{}還是catch{}發生了什麽,finally{}中的語句一定會運行到

這點可以通過結果1234看到,"finally block."怎麽樣都是打印出來的

C、當try{}或是catch{}發生return時,方法並不是立即返回的,而是等finally{}執行完畢後,才返回

這點可以通過結果34看到,在打印結果"1"或"2"的前一行,"finally block."被打印出來了

D、如果設計不當,使finally{}中存在return語句,那麽執行當finally{return}時,方法會直接返回,finally{}執行之前預定需要返回的返回值,會被覆蓋掉

這點可以通過結果12看到,返回值都是finally裏的3而不是try裏的1或catch裏的2。

C、D可以如此理解,沒有返回語句的finally{}比較本分,try{}、catch{}顧及到語言限定,在返回前給了finally{}運行的機會,finally運行完畢後返回正確的值;

但編碼使另finally{}中出現返回語句,那麽finally{}就像是一個過河拆橋的人,利用try{}或是catch{}給的機會,執行了自己的返回語句,讓方法直接結束,try{return}或catch{return}再也沒有機會返回了。

Try-Catch-Finally代碼塊中的return