【JAVA基礎總結】try-catch-finally執行順序

1、try{}catch(){}finally{} return;

package test;

public class TryCatchFinallyTest {

    public static void main(String[] args) {
        int result = test();
        System.out.println("返回結果..." + result);
    }
    
    private static int test() {
        int numerator = 1;
        int denominator = 10;// 不拋異常時
//        int denominator = 0;// 拋異常時
        int calculate = 0;
        
        try {
            System.out.println("執行try...");
            calculate = numerator/denominator;
            System.out.println("執行try..." + calculate);
        } catch (Exception e) {
            System.out.println("執行catch..." + calculate);
        } finally {
            calculate ++;
            System.out.println("執行finally..." + calculate);
        }
        
        return calculate;
    }

}
  • 當不拋異常時,結果如下:
執行try...
執行try...0
執行finally...1
返回結果...1

可見,執行順序爲try-finally,然後return。

  • 當拋異常時,結果如下:
執行try...
執行catch...0
執行finally...1
返回結果...1

可見,執行順序爲try-catch-finally,然後return。

所以不管有木有出現異常,finally塊中代碼都會執行;

2、try{return;}catch(){}finally{} return;

package test;

public class TryCatchFinallyTest {

    public static void main(String[] args) {
        int result = test();
        System.out.println("返回結果..." + result);
    }
    
    private static int test() {
        int numerator = 1;
        int denominator = 10;// 不拋異常時
        int calculate = 0;
        
        try {
            System.out.println("執行try開始");
            calculate = numerator/denominator;
            System.out.println("執行try..." + calculate);
            
            return calculate++;
        } catch (Exception e) {
            System.out.println("執行catch..." + calculate);
        } finally {
            System.out.println("執行finally開始" + calculate);
            calculate++;
            System.out.println("執行finally結束" + calculate);
        }
        
        System.out.println("calculate=" + calculate);
        
        return calculate;
    }

}

結果如下:

執行try開始
執行try...0
執行finally開始1
執行finally結束2
返回結果...0

你可能會很好奇,爲啥結果是0,不應該是2嗎?先不急,我們先縷清下這個執行順序:

  • 首先程序執行try塊中return之前(包括return語句中的表達式運算)代碼,此時calculate值爲0(該值就是return的值,將會被保存到棧中);
  • 再進入finally塊中,此時calculate值爲1(由於try中執行了calculate++);然後執行finally塊中代碼,這時calculate值變爲2;
  • 最後執行try中return,即返回try中被保存在棧中的值;
  • 由於try中已經return了,所以不再執行finally塊之後的代碼。

3、try{}catch(){return;}finally{} return;

package test;

public class TryCatchFinallyTest {

    public static void main(String[] args) {
        int result = test();
        System.out.println("返回結果..." + result);
    }
    
    private static int test() {
        int numerator = 1;
        int denominator = 0;// 拋異常時
        int calculate = 0;
        
        try {
            System.out.println("執行try開始");
            calculate = numerator/denominator;
            System.out.println("執行try..." + calculate);
        } catch (Exception e) {
            System.out.println("執行catch..." + calculate);
            return ++calculate;
        } finally {
            System.out.println("執行finally開始" + calculate);
            calculate++;
            System.out.println("執行finally結束" + calculate);
        }
        
        System.out.println("calculate=" + calculate);
        
        return calculate;
    }

}

結果如下:

執行try開始
執行catch...0
執行finally開始1
執行finally結束2
返回結果...1

有了上面的例子,看到這個結果你可能不會那麼的震驚了,但還是有點疑問,爲毛返回結果不是0?哈哈,這個你得補補calculate++和++calculate的知識了,這兒不再細說。

我們看下這個執行順序:

  • 首先程序執行try塊中代碼,此時calculate值爲0;
  • 遇到異常執行catch塊中return之前(包括return語句中的表達式運算)代碼,此時calculate值爲1;
  • 再進入finally塊中,此時calculate值爲1(由於catch中執行了++calculate);然後執行finally塊中代碼,這時calculate值變爲2;
  • 最後執行try中return,即返回try中被保存在棧中的值;
  • 由於catch中已經return了,所以不再執行finally塊之後的代碼。

1、當try和catch中有return時,finally仍然會執行;

2、finally是在return後面的表達式運算後執行的(此時並沒有返回運算後的值,而是先把要返回的值保存起來,不管finally中的代碼怎麼樣,返回的值都不會改變,仍然是之前保存的值),所以函數返回值是在finally執行前確定的;

4、try{return;}catch(){}finally{return;}

package test;

public class TryCatchFinallyTest {

    public static void main(String[] args) {
        int result = test();
        System.out.println("返回結果..." + result);
    }
    
    private static int test() {
        int numerator = 1;
        int denominator = 10;// 不拋異常時
        int calculate = 0;
        
        try {
            System.out.println("執行try開始");
            calculate = numerator/denominator;
            System.out.println("執行try..." + calculate);
            return calculate++;
        } catch (Exception e) {
            System.out.println("執行catch..." + calculate);
        } finally {
            System.out.println("執行finally開始" + calculate);
            calculate++;
            System.out.println("執行finally結束" + calculate);
            return calculate;
        }
    }

}

結果如下:

執行try開始
執行try...0
執行finally開始1
執行finally結束2
返回結果...2

通過列子2可以很清晰地明白爲啥是這個結果了吧。其實就是執行finally塊中代碼時遇到了return提前退出了而已。

5、try{}catch(){return;}finally{return;}

package test;

public class TryCatchFinallyTest {

    public static void main(String[] args) {
        int result = test();
        System.out.println("返回結果..." + result);
    }
    
    private static int test() {
        int numerator = 1;
        int denominator = 0;// 拋異常時
        int calculate = 0;
        
        try {
            System.out.println("執行try開始");
            calculate = numerator/denominator;
            System.out.println("執行try..." + calculate);
        } catch (Exception e) {
            System.out.println("執行catch..." + calculate);
            return ++calculate;
        } finally {
            System.out.println("執行finally開始" + calculate);
            calculate++;
            System.out.println("執行finally結束" + calculate);
            return calculate;
        }
    }

}

結果如下:

執行try開始
執行catch...0
執行finally開始1
執行finally結束2
返回結果...2

可以參考例子3,啊哈哈。

所以finally中最好不要包含return,否則程序會提前退出,返回值不是try或catch中保存的返回值。

總結

  1. 任何執行try或者catch中的return語句之前,都會先執行finally語句,如果finally存在的話。
  2. 如果finally中有return語句,那麼程序就return了,所以finally中的return是一定會被return的,編譯器把finally中的return實現爲一個warning。

參考

http://blog.csdn.net/kavensu/article/details/8067850

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