Java try catch finally

壹頁書發表於2016-05-17
參考:
https://www.ibm.com/developerworks/cn/java/j-lo-finally/
http://www.cnblogs.com/lanxuezaipiao/p/3440471.html



finally 語句塊一定會執行嗎?
有兩個前提條件
1.try塊已經得到執行
2.不能出現Error.比如關停了JVM

finally塊執行的時機
try或者catch return的語句執行時候,但是在實際return之前,執行finally

如果try或者catch中有返回,finally塊的定位
相當於在try或者catch中呼叫了一個函式.和普通函式呼叫中傳值,傳址那套.一樣一樣的.

如果finally中有return,會直接覆蓋try或者catch中的return

開始舉栗子:
1.finally語句在return語句執行之後return返回之前執行的。
  1. public class T {  
  2.     public static void main(String[] args) {  
  3.   
  4.         System.out.println(test1());  
  5.     }  
  6.   
  7.     public static int test1() {  
  8.         int b = 20;  
  9.   
  10.         try {  
  11.             System.out.println("try block");  
  12.   
  13.             return b += 80;  
  14.         } catch (Exception e) {  
  15.   
  16.             System.out.println("catch block");  
  17.         } finally {  
  18.   
  19.             System.out.println("finally block");  
  20.   
  21.             if (b > 25) {  
  22.                 System.out.println("b>25, b = " + b);  
  23.             }  
  24.         }  
  25.   
  26.         return b;  
  27.     }  
  28. }  

結果:
try block
finally block
b>25, b = 100
100

說明try塊中的b+=80 已經執行完畢,才進入finally塊.

2.finally塊中的return語句會覆蓋try塊中的return返回。
  1. public class T {  
  2.     public static void main(String[] args) {  
  3.   
  4.         System.out.println(test2());  
  5.     }  
  6.   
  7.     public static int test2() {  
  8.         int b = 20;  
  9.   
  10.         try {  
  11.             System.out.println("try block");  
  12.   
  13.             return b += 80;  
  14.         } catch (Exception e) {  
  15.   
  16.             System.out.println("catch block");  
  17.         } finally {  
  18.   
  19.             System.out.println("finally block");  
  20.   
  21.             if (b > 25) {  
  22.                 System.out.println("b>25, b = " + b);  
  23.             }  
  24.   
  25.             return 200;  
  26.         }  
  27.   
  28.         // return b;  
  29.     }  
  30. }  

try block
finally block
b>25, b = 100
200

也就是說如果finally中有return語句,會覆蓋原來try或者catch中的return語句.

3.如果finally語句中沒有return語句覆蓋返回值,那麼原來的返回值可能因為finally裡的修改而改變也可能不變。
就是原來傳值,傳址那一套...

所謂傳值的..
  1. public class T {  
  2.     public static void main(String[] args) {  
  3.   
  4.         System.out.println(test3());  
  5.     }  
  6.   
  7.     public static int test3() {  
  8.         int b = 20;  
  9.   
  10.         try {  
  11.             System.out.println("try block");  
  12.             return b += 80;  
  13.         } catch (Exception e) {  
  14.   
  15.             System.out.println("catch block");  
  16.         } finally {  
  17.   
  18.             System.out.println("finally block");  
  19.   
  20.             if (b > 25) {  
  21.                 System.out.println("b>25, b = " + b);  
  22.             }  
  23.   
  24.             b = 150;  
  25.         }  
  26.   
  27.         //有異常才會執行如下返回  
  28.         return 2000;  
  29.     }  
  30. }  

結果:
try block
finally block
b>25, b = 100
100

傳址的
  1. import java.util.HashMap;  
  2. import java.util.Map;  
  3.   
  4. public class T {  
  5.     public static void main(String[] args) {  
  6.         System.out.println(getMap().get("KEY").toString());  
  7.     }  
  8.   
  9.     public static Map getMap() {  
  10.         Map map = new HashMap();  
  11.         map.put("KEY""INIT");  
  12.   
  13.         try {  
  14.             map.put("KEY""TRY");  
  15.             return map;  
  16.         } catch (Exception e) {  
  17.             map.put("KEY""CATCH");  
  18.         } finally {  
  19.             map.put("KEY""FINALLY");  
  20.             map = null;  
  21.         }  
  22.   
  23.         return map;  
  24.     }  
  25. }  


結果:
FINALLY

傳值傳址本身就是一個不嚴謹的說法.
剛才傳值的情況,如果將int改為Integer

  1. public class T {  
  2.     public static void main(String[] args) {  
  3.         System.out.println(test3());  
  4.     }  
  5.   
  6.     public static Integer test3() {  
  7.         Integer b = new Integer(20);  
  8.           
  9.         try {  
  10.             System.out.println("try block");  
  11.   
  12.             return b += 80;  
  13.         } catch (Exception e) {  
  14.   
  15.             System.out.println("catch block");  
  16.         } finally {  
  17.   
  18.             System.out.println("finally block");  
  19.   
  20.             if (b > 25) {  
  21.                 System.out.println("b>25, b = " + b);  
  22.             }  
  23.   
  24.             b = new Integer(150);  
  25.         }  
  26.   
  27.         return 2000;  
  28.     }  
  29. }  
結果:
try block
finally block
b>25, b = 100
100

給我的感覺,finally和以下的程式碼差不多
所以除非透過 指標b,修改原來物件的實際內容.
否則,修改 指標b指向別的物件,或者將指標b設定為null.都不能影響原來函式的返回值.

  1. public class T {  
  2.     public static void main(String[] args) {  
  3.         System.out.println(test3());  
  4.     }  
  5.   
  6.     public static Integer test3() {  
  7.         Integer b = new Integer(20);  
  8.         System.out.println("try block");  
  9.         b += 80;  
  10.         funcFinally(b);  
  11.         return b;  
  12.     }  
  13.   
  14.     private static void funcFinally(Integer b) {  
  15.   
  16.         System.out.println("finally block");  
  17.   
  18.         if (b > 25) {  
  19.             System.out.println("b>25, b = " + b);  
  20.         }  
  21.   
  22.         b = new Integer(150);  
  23.     }  
  24. }  

4.try塊裡的return語句在異常的情況下不會被執行。

  1. public class T {  
  2.     public static void main(String[] args) {  
  3.   
  4.         System.out.println(test4());  
  5.     }  
  6.   
  7.     public static int test4() {  
  8.         int b = 20;  
  9.         try {  
  10.             System.out.println("try block");  
  11.             b = b / 0;  
  12.             System.out.println("墓誌銘:我覺得還能再搶救一下");  
  13.             return b += 80;  
  14.         } catch (Exception e) {  
  15.             b += 15;  
  16.             System.out.println("catch block");  
  17.         } finally {  
  18.             System.out.println("finally block");  
  19.             if (b > 25) {  
  20.                 System.out.println("b>25, b = " + b);  
  21.             }  
  22.             b += 50;  
  23.         }  
  24.         return b;  
  25.     }  
  26. }  

由於程式碼11行發生異常,直接進入catch,finally處理.最終在24行返回.

注意這個時候,catch和finally塊對b的修改,都可以反映在最終的結果中.

結果:
try block
catch block
finally block
b>25, b = 35
85

5.當發生異常後,catch中的return執行情況與未發生異常時try中return的執行情況完全一樣。

  1. public class T {  
  2.     public static void main(String[] args) {  
  3.   
  4.         System.out.println(test5());  
  5.     }  
  6.   
  7.     public static int test5() {  
  8.         int b = 20;  
  9.         try {  
  10.             System.out.println("try block");  
  11.             b = b / 0;  
  12.             return b += 80;  
  13.         } catch (Exception e) {  
  14.             System.out.println("catch block");  
  15.             return b += 15;  
  16.         } finally {  
  17.             System.out.println("finally block");  
  18.             if (b > 25) {  
  19.                 System.out.println("b>25, b = " + b);  
  20.             }  
  21.             b += 50;  
  22.         }  
  23.         // return b;  
  24.     }  
  25. }  

結果:
try block
catch block
finally block
b>25, b = 35
35


程式媛的總結:
最後總結:finally塊的語句在try或catch中的return語句執行之後返回之前執行且finally裡的修改語句可能影響也可能不影響try或catch中 return已經確定的返回值
若finally裡也有return語句則覆蓋try或catch中的return語句直接返回。


我覺得吧...finally就別寫return了.


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-2101289/,如需轉載,請註明出處,否則將追究法律責任。

相關文章