1. 程式人生 > >Java finally語句到底是在return之前還是之後執行

Java finally語句到底是在return之前還是之後執行

異常捕獲 main ++ class static 輸出 tps turn system

看過網上關於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 = 1;

         try {           
             System.out.println("try block");           
             return ++b;             
         }
         catch (Exception e) {           
             b = 10;
             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
  • 1
  • 2
  • 3

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

這個時候,咱打斷點看看:
(1). 當程序執行到try中的return語句時,這時b還是1.
技術分享圖片
(2). 接著程序執行到finally語句時,執行了++b,b變為2.
技術分享圖片
(3). 這時,我們點擊try…return中的b,發現其值變為2.
技術分享圖片

以上結果說明了一點: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
  • 1

可能大家會繼續說,如果finally和catch中有return,那是一種什麽情況:
(1) 首先看catch中有return

 public static int test4() {

         int b = 1;

         try {

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

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

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

結果

try block
catch block
finally block
2

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

(2) 然後看finally中有return

public static int test5() {

         int b = 1;

         try {

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

         }
         catch (Exception e) {

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

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

結果

try block
finally block
12

可見,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 = 1;

         try {

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

         }
         catch (Exception e) {

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

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

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

執行結果:

 catch block
finally block
last block
20

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

總結:

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

Java finally語句到底是在return之前還是之後執行