異常處理中,try、catch、finally的執行順序,你們都知道是按順序執行的。即,若是try中沒有異常,則順序爲try→finally,若是try中有異常,則順序爲try→catch→finally。可是當try、catch、finally中加入return以後,就會有幾種不一樣的狀況出現,下面分別來講明一下。也能夠跳到最後直接看總結。spa
1、try中帶有returncode
1 private int testReturn1() { 2 int i = 1; 3 try { 4 i++; 5 System.out.println("try:" + i); 6 return i; 7 } catch (Exception e) { 8 i++; 9 System.out.println("catch:" + i); 10 } finally { 11 i++; 12 System.out.println("finally:" + i); 13 } 14 return i; 15 }
輸出:blog
try:2
finally:3
2編譯器
由於當try中帶有return時,會先執行return前的代碼,而後暫時保存須要return的信息,再執行finally中的代碼,最後再經過return返回以前保存的信息。因此,這裏方法返回的值是try中計算後的2,而非finally中計算後的3。但有一點須要注意,再看另一個例子:io
1 private List<Integer> testReturn2() { 2 List<Integer> list = new ArrayList<>(); 3 try { 4 list.add(1); 5 System.out.println("try:" + list); 6 return list; 7 } catch (Exception e) { 8 list.add(2); 9 System.out.println("catch:" + list); 10 } finally { 11 list.add(3); 12 System.out.println("finally:" + list); 13 } 14 return list; 15 }
輸出:編譯
try:[1]
finally:[1, 3]
[1, 3]class
看完這個例子,可能會發現問題,剛提到return時會臨時保存須要返回的信息,不受finally中的影響,爲何這裏會有變化?其實問題出在參數類型上,上一個例子用的是基本類型,這裏用的引用類型。list裏存的不是變量自己,而是變量的地址,因此當finally經過地址改變了變量,仍是會影響方法返回值的。test
2、catch中帶有return變量
1 private int testReturn3() { 2 int i = 1; 3 try { 4 i++; 5 System.out.println("try:" + i); 6 int x = i / 0 ; 7 } catch (Exception e) { 8 i++; 9 System.out.println("catch:" + i); 10 return i; 11 } finally { 12 i++; 13 System.out.println("finally:" + i); 14 } 15 return i; 16 }
輸出:List
try:2
catch:3
finally:4
3
catch中return與try中同樣,會先執行return前的代碼,而後暫時保存須要return的信息,再執行finally中的代碼,最後再經過return返回以前保存的信息。因此,這裏方法返回的值是try、catch中累積計算後的3,而非finally中計算後的4。
3、finally中帶有return
1 private int testReturn4() { 2 int i = 1; 3 try { 4 i++; 5 System.out.println("try:" + i); 6 return i; 7 } catch (Exception e) { 8 i++; 9 System.out.println("catch:" + i); 10 return i; 11 } finally { 12 i++; 13 System.out.println("finally:" + i); 14 return i; 15 } 16 }
輸出:
try:2
finally:3
3
當finally中有return的時候,try中的return會失效,在執行完finally的return以後,就不會再執行try中的return。這種寫法,編譯是能夠編譯經過的,可是編譯器會給予警告,因此不推薦在finally中寫return,這會破壞程序的完整性,並且一旦finally裏出現異常,會致使catch中的異常被覆蓋。
總結:
一、finally中的代碼總會被執行。
二、當try、catch中有return時,也會執行finally。return的時候,要注意返回值的類型,是否受到finally中代碼的影響。
三、finally中有return時,會直接在finally中退出,致使try、catch中的return失效。