天天看点

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,则其执行后的结果会直接返回。