天天看點

Java finally語句到底是在return之前還是之後執行?---第一篇

當return遇到finally

看過網上關于Java中異常捕獲機制try…catch…finally塊中的finally語句是不是一定會被執行的讨論也有很多。

首先明确一點,下面兩種情況finally肯定是不執行的:

1). return語句在try之前,還沒執行就傳回了,當然不執行。

2). try語句中用了system.exit(0)強制退出JVM,暴力退出當然也不會執行。

先來看下面的代碼

package com.loongshaw;

public class TryReturnFinally {

     public static void main(String[] args) {

         System.out.println(test1());        
     }

     public static int test1() {

         int b = ;

         try {           
             System.out.println("try block");           
             return ++b;             
         }
         catch (Exception e) {           
             b = ;
             System.out.println("catch block");
         }
         finally {              
             ++b;
             System.out.println("finally block");
         }       
         System.out.println("last block");
         return b;
     }
}
           

如果你覺得其執行結果是3,那麼請你繼續看下去,中招了吧,哈哈。

先看看執行結果吧:

try block
finally block

           

可以看出,上面代碼的執行結果是2。正常想法其finally也執行了,try中也執行了,明明執行了兩個++b呢,咋回事呢?

這個時候,咱打斷點看看:

(1). 當程式執行到try中的return語句時,這時b還是1.

Java finally語句到底是在return之前還是之後執行?---第一篇

(2). 接着程式執行到finally語句時,執行了++b,b變為2.

Java finally語句到底是在return之前還是之後執行?---第一篇

(3). 這時,我們點選try…return中的b,發現其值變為2.

Java finally語句到底是在return之前還是之後執行?---第一篇

以上結果說明了一點:return語句執行了,然後再執行了finally語句,但是return語句并沒有直接傳回,而是待finally語句執行完了再傳回。

通過下面這個測試用例加強了解:

package com.loongshaw;

public class TryReturnFinally {

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

     public static String test2() {

         try {

             System.out.println("try block");           
             return test3();             
         }
         catch (Exception e) {

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

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

         System.out.println("last block");
         return "last block";
     }

     public static String test3() {                      
         System.out.println("return block");
         return "output return block";
     }

}
           

執行結果:

try block
return block
finally block
output return block
           

通過上述結果可以得出,在執行try語句中的return時,其test3()方法是被執行了的,其傳回值儲存在一個臨時變量中,然後去執行finally語句。

try {           
       System.out.println("try block");         
       return test3();           
    }
           

最後輸出存進臨時變量傳回值。

output return block
           

可能大家會繼續說,如果finally和catch中有return,那是一種什麼情況:

(1) 首先看catch中有return

public static int test4() {

         int b = ;

         try {

             System.out.println("try block");           
             return b/; 

         }
         catch (Exception e) {
             System.out.println("catch block");
             return ++b;
         }
         finally {

             b = b+ ;
             System.out.println("finally block");
         }
     }
           

結果

try block
catch block
finally block

           

可見,catch中的return與try一樣,finally都會執行,但是不影響try和catch中的return結果。

(2) 然後看finally中有return

public static int test5() {

         int b = ;

         try {

             System.out.println("try block");           
             return ++b; 

         }
         catch (Exception e) {

             ++b;
             System.out.println("catch block");
             return b;
         }
         finally {

             b = b+ ;
             System.out.println("finally block");
             return b;
         }
     }
           

結果

try block
finally block

           

可見,finally中的return直接傳回了,這與try和catch中的return是不同的。

大家可能發現test1()方法最後的return是沒有執行的,是不是。

public static int test1() {  
    ...    
    System.out.println("last block");
    return b;
    ...
}
           

通常情況是不會執行的,除非觸發了catch。下面是修改後的片段代碼:

public static int test1() {

         int b = ;

         try {

             b = b/;
             System.out.println("try block");           
             return ++b; 

         }
         catch (Exception e) {

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

             b = b+ ;
             System.out.println("finally block");
         }

         System.out.println("last block");
         return b;
     }
           

執行結果:

catch block
finally block
last block

           

通過上述結果可以得出,在catch觸發時,最外層的return是會被執行的。

總結:

  1. finally語句在try和catch語句中的return執行後、傳回前執行;
  2. 若finally語句中沒有return,則其執行結果不影響try和catch中已确定的傳回值;
  3. 若finally語句中有return,則其執行後的結果會直接傳回。