JAVA try-catch-finally-return

 
  • 正常執行流程
try執行,遇到異常就跳到catch 執行(以使得程序不會崩潰)
無論有沒有異常 catch, 最後都執行finally
 
  • return語句執行流程分析
若try塊中return 可達,  return語句(如:return x=x+1;)
  1. 對x執行運算x=x+1 (如有運算)
  2. 複製一個變量x給try的return語句(按值複製:基本類型就是值自己,對象就是地址值
  3. return語句並不立刻返回控制權轉移到finally塊中執行: (1)若finally中無return語句finally執行完後try塊執行return語句返回以前複製的變量x(基本類型就是值自己,對象就是地址值)(因此:若x爲基本類型,fianlly中改變x對最終return結果無效;若x爲對象類型,按地址值傳遞能夠改變x的最終return結果)    (2)若finally中有return語句:執行後直接返回(即「覆蓋try中return語句」:try中return語句再也不返回
 
若try中return 不可達(exception 在return前出現
    exception出現後 控制權直接轉到 catch  塊(即 try中  exception以後的語句<包括return>不會執行 ),最後到finally塊(catch到finally中流程與上面try 到finally中流程相同
 
 
  • finally不執行的特殊狀況
  1. if you call System.exit() or
  2. if the JVM crashes first
 
  • A return statement in the finally block is a bad idea
By doing a return from the finally block, you suppress the exception entirely. finally 中有return ,try,catch的 return throw都不會再被調用
  1. publicstaticint getANumber(){
  2.     try{
  3.         thrownewNoSuchFieldException();
  4.     } finally {
  5.         return43;
  6.     }
  7. }
Running the method above will return a 「43」 and the exception in the try block will not be thrown. This is why it is considered to be a very bad idea to have a return statement inside the finally block.
 
 

例子解釋:
 
執行流程

  1. If the return in the try block is reached, it transfers control to the finally block, and the function eventually returns normally (not a throw).
  2. If an exception occurs, but then the code reaches a return from the catch block, control is transferred to the finally block and the function eventually returns normally (not a throw).
  3. In your example, you have a return in the finally, and so regardless of what happens, the function will return 34, because finally has the final (if you will) word.
 
 
finally語句在try或catch中的return語句執行以後、return返回以前執行的
  • 在try中含有return+基本類型狀況:
  1. publicclassFinallyTest1{
  2.     publicstaticvoid main(String[] args){
  3.         System.out.println(test1());
  4.     }
  5.     publicstaticint test1(){
  6.         int b =20;
  7.         try{
  8.             System.out.println("try block");
  9.             return b +=80;
  10.         }
  11.         catch(Exception e){
  12.             System.out.println("catch block");
  13.         }
  14.         finally {
  15.             System.out.println("finally block");
  16.             if(b >25){
  17.                 System.out.println("b>25, b = "+ b);
  18.             }
  19.         }
  20.         return b;
  21.     }
  22. }
運行結果:
  1. try block
  2. finally block
  3. b>25, b =100
  4. 100
 
  • 在catch中含有return+基本類型狀況(分析跟在try中含有return狀況同樣):
  1. publicclassTest{
  2.  
  3.     publicstaticvoid main(String[] args){
  4.  
  5.         System.out.println(test1());
  6.     }
  7.  
  8.     publicstaticint test1(){
  9.         int b =20;
  10.  
  11.         try{
  12.             int a =1/0;//觸發異常
  13.             System.out.println("try block");//不會被執行
  14.             return b +=80;//不會被執行
  15.         }
  16.         catch(Exception e){
  17.             System.out.println("catch block");
  18.             return b +=180;//最後在此返回
  19.         }
  20.         finally {
  21.             System.out.println("finally block");
  22.             if(b >25){
  23.                 System.out.println("b>25, b = "+ b);
  24.             }
  25.         }
  26. //        return b;
  27.     }
  28.  
  29. }
執行結果:
  1. catch block
  2. finally block
  3. b>25, b =200
  4. 200
 
  • 在try中含有return+對象類型狀況:
  1. publicclassTest{
  2.  
  3.     publicstaticvoid main(String[] args){
  4.         System.out.println(getMap().get("KEY").toString());
  5.     }
  6.  
  7.     publicstaticMap<String,String> getMap(){
  8.         Map<String,String>map=newHashMap<String,String>();
  9.         map.put("KEY","INIT");
  10.  
  11.         try{
  12.             map.put("KEY","TRY");
  13.             returnmap;//return在控制權轉移到finally前:複製了一個map對象的地址值(對象按地址值傳遞)
  14.         }
  15.         catch(Exception e){
  16.             map.put("KEY","CATCH");
  17.         }
  18.         finally {
  19.             map.put("KEY","FINALLY");//根據對象地址值修改對象內容(按地址值傳遞),所以會影響try中return返回的對象內容
  20.             map= null;//map爲null即再也不指向該對象,
  21.             // 但因爲前面return複製了一個對象的引用(地址值),而對象是被分配在堆中的,只要有引用指向這個對象,系統就不會回收此對象, 因此此處map = null 並不會影響最後try中return返回對象內容
  22.         }
  23.  
  24.         returnmap;
  25.     }
  26.  
  27. }
執行結果:
  1. FINALLY

  • 在catch中含有return+基本類型狀況(分析跟在try中含有return狀況同樣):
  1. publicclassTest{
  2.  
  3.     publicstaticvoid main(String[] args){
  4.         System.out.println(getMap().get("KEY").toString());
  5.     }
  6.  
  7.     publicstaticMap<String,String> getMap(){
  8.         Map<String,String>map=newHashMap<String,String>();
  9.         map.put("KEY","INIT");
  10.  
  11.         try{
  12.             int a =1/0;//觸發異常
  13.             map.put("KEY","TRY");//不會被執行
  14.             returnmap;//不會被執行
  15.         }
  16.         catch(Exception e){
  17.             map.put("KEY","CATCH");
  18.             returnmap;//return在控制權轉移到finally前:複製了一個map對象的地址值(對象按地址值傳遞)
  19.         }
  20.         finally {
  21.             map.put("KEY","FINALLY");//根據對象地址值修改對象內容(按地址值傳遞),所以會影響catch中return返回的對象內容
  22.             map= null;//map爲null即再也不指向該對象,
  23.             // 但因爲前面return複製了一個對象的引用(地址值),而對象是被分配在堆中的,只要有引用指向這個對象,系統就不會回收此對象,
  24.             // 因此此處map = null 並不會影響最後catch中return返回對象內容
  25.         }
  26.  
  27. //        return map;
  28.     }
  29.  
  30. }
執行結果:
  1. FINALLY
 
 
finally塊中的return語句會覆蓋try塊中的return返回
  1. publicclassTest{
  2.  
  3.     publicstaticvoid main(String[] args){
  4.  
  5.         System.out.println(test2());
  6.     }
  7.  
  8.     publicstaticint test2(){
  9.         int b =20;
  10.  
  11.         try{
  12.             System.out.println("try block");
  13.             return b +=80;
  14.         }catch(Exception e){
  15.             System.out.println("catch block");
  16.         } finally {
  17.             System.out.println("finally block");
  18.             if(b >25){
  19.                 System.out.println("b>25, b = "+ b);
  20.             }
  21.             return200;
  22.         }
  23.         // return b;
  24.     }
  25.  
  26. }
執行結果:
  1. try block
  2. finally block
  3. b>25, b =100
  4. 200
 
參考: http://www.cnblogs.com/lanxuezaipiao/p/3440471.html (博文代碼用例4結果有誤,見該博文討論區分析)
 
 
 
 
 
 
 



相關文章
相關標籤/搜索