深入理解finally关键字,Finally到底是在return前面执行还是在return后面执行

Posted xhlwjy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解finally关键字,Finally到底是在return前面执行还是在return后面执行相关的知识,希望对你有一定的参考价值。

一:2种finally不会执行的情况

  a.在try语句之前就return了

  b.try语句中有System.exit();语句

二:finally语句在return执行之后,return返回之前执行

  例1:

public class FinallyTest1 
    public static void main(String[] args) 
        test1();
    
    public static int test1()
        int b=20;
        try 
            System.out.println("try block");
            return b += 80;
        
        catch (Exception e) 
            System.out.println("catch block");
        
        finally 
            System.out.println("finally block");
            if (b > 25) 
                System.out.println("b>25, b = " + b);
            
        
        return b;
    

console:

技术图片
try block
finally block
b>25, b = 100
View Code

说明:在return b += 80;后先执行finally语句

再来一个例子加强这个事实

例2

public class FinallyTest1 
    public static void main(String[] args) 
        System.out.println(test11());
    
    public static String test11() 
        try 
            System.out.println("try block");
            return test12();
         finally 
            System.out.println("finally block");
        
    
    public static String test12() 
        System.out.println("return statement");
        return "after return";
    

console:

技术图片
try block
return statement
finally block
after return
View Code

说明:先执行了return 语句中的方法,然后返回值

 

三:如果finally中有return语句呢?

public class FinallyTest1 
    public static void main(String[] args) 
        System.out.println(test2());
    
    public static int test2() 
        int b = 20;
        try 
            System.out.println("try block");
            return b += 80;
         catch (Exception e) 
            System.out.println("catch block");
         finally 
            System.out.println("finally block");
            if (b > 25) 
                System.out.println("b>25, b = " + b);
            
            return 200;
        
        // return b;
    

console:

技术图片
try block
finally block
b>25, b = 100
200
View Code

说明:finally里的return直接返回了,就不管try中是否还有返回语句,这里还有个小细节需要注意,finally里加上return过后,finally外面的return b就变成不可到达语句了,也就是永远不能被执行到,所以需要注释掉否则编译器报错。

四:如果finally语句中没有return语句覆盖返回值,那么原来的返回值可能因为finally里的修改而改变也可能不变。

 

public class FinallyTest1 
    public static void main(String[] args) 
        System.out.println(test3());
    
    public static int test3() 
        int b = 20;
        try 
            System.out.println("try block");
            return b += 80;
         catch (Exception e) 
            System.out.println("catch block");
         finally 
            System.out.println("finally block");
            if (b > 25) 
                System.out.println("b>25, b = " + b);
            
            b = 150;
        
        return 2000;
    

console:

技术图片
try block
finally block
b>25, b = 100
100
View Code

对比下面的这个程序

public class FinallyTest1 
    public static void main(String[] args) 
        System.out.println(getMap().get("KEY").toString());
    
    public static Map<String, String> getMap() 
        Map<String, String> map = new HashMap<String, String>();
        map.put("KEY", "INIT");
        try 
            map.put("KEY", "TRY");
            return map;
        
        catch (Exception e) 
            map.put("KEY", "CATCH");
        
        finally 
            map.put("KEY", "FINALLY");
            map = null;
        
        return map;
    

console:

技术图片
FINALLY
View Code

说明:为什么测试用例1中finally里的b = 150;并没有起到作用而测试用例2中finally的map.put("KEY", "FINALLY");起了作用而map = null;却没起作用呢?这就是Java到底是传值还是传址的问题了

    1.值传递不可以改变原变量的内容和地址;

   2.引用传递不可以改变原变量的地址,但可以改变原变量的内容;

    3.注意String str = new String("good")特殊,因为String是个特殊的final类,所以每次对String的更改都会重新创建内存地址并存储(也可能是在字符串常量池中创建内存地址并存入对应的字符串内容),但是因为这里String是作为参数传递的,在方法体内会产生新的字符串而不会对方法体外的字符串产生影响。相当于值传递

 

五:是不是每次返回的一定是try中的return语句呢?那么finally外的return b不是一点作用没吗?

public class FinallyTest1 
    public static void main(String[] args) 
        System.out.println(test4());
    
    public static int test4() 
        int b = 20;
        try 
            System.out.println("try block");
            b = b / 0;
            return b += 80;
         catch (Exception e) 
            b += 15;
            System.out.println("catch block");
         finally 
            System.out.println("finally block");
            if (b > 25) 
                System.out.println("b>25, b = " + b);
            
            b += 50;
        
        return b;
    

console:

技术图片
try block
catch block
finally block
b>25, b = 35
85
View Code

 

六:若发生异常,catch语句中的return语句和try中的return语句的情况一模一样

public class FinallyTest1 
    public static void main(String[] args) 
        System.out.println(test5());
    
    public static int test5() 
        int b = 20;
        try 
            System.out.println("try block");
            b = b /0;
            return b += 80;
         catch (Exception e) 
            System.out.println("catch block");
            return b += 15;
         finally 
            System.out.println("finally block");
            if (b > 25) 
                System.out.println("b>25, b = " + b);
            
            b += 50;
        
        //return b;
    

console:

技术图片
try block
catch block
finally block
b>25, b = 35
35
View Code

 

 

总结:还是例1前面的一句话:

finally语句在return执行之后,return返回之前执行

以上是关于深入理解finally关键字,Finally到底是在return前面执行还是在return后面执行的主要内容,如果未能解决你的问题,请参考以下文章

关键字“finally”是如何在 PHP 中使用的?

Java finally语句到底是在return之前还是之后执行?

Java finally语句到底是在return之前还是之后执行?

Java finally语句到底是在return之前还是之后执行?

Java finally语句到底是在return之前还是之后执行?

Java finally语句到底是在return之前还是之后执行?