return 和 finally究竟谁先被执行?

一直对return和finnally谁先执行没有理得很清楚,今天就来对return和finally做一个彻底详细的总结吧!

1:无论程序从try或catch中返回,finally总会被执行。并且finally语句是在return语句执行之后、返回之前执行的。

try/finally:

public class tryDemo {
    public static int show() {
        try {
            return 1;
        }finally{
            System.out.println("finally模块被执行");
        }
    }
    public static void main(String args[]) {
        System.out.println(show());
    }
}

结果:


catch/finally:

public class tryDemo {
    public static int show() {
        try {
            int a = 8/0;
            return 1;
        }catch (Exception e) {
            return 2;
        }finally{
            System.out.println("finally模块被执行");
        }
    }
    public static void main(String args[]) {
        System.out.println(show());
    }
}

结果:

2:finally中的语句对变量的修改是否生效要看变量的类型
1)如果return的数据是基本数据类型或文本字符串,则在finally中对该基本数据的改变不起作用,try中的return语句依然会返回进入finally块之前保留的值。

2)如果return的数据是引用数据类型,而在finally中对该引用数据类型的属性值的改变起作用,try中的return语句返回的就是在finally中改变后的该属性的值。

这里又顺便想到String这种情况,String字符串虽然为引用类型,但是在finally改变的时候,其实当于申请了一个新的字符串,所以原来地址的字符串并没有改变,所以finally中的改变不会生效。如把string由“123”改为“456”,效果如下图:



而若是用StringBuilder/StringBuffer的话,就是正经的引用类型变量了,比如给StringBuffer b 来append一个“456”,会是下图:



用代码验证一下:
 public class TestTryCatch {
    public static void main(String[] args)
    {
        TestTryCatch test = new TestTryCatch();
        System.out.println(test.fun());
    }
 
    public StringBuilder fun()
    {
        StringBuilder s = new StringBuilder("Hello");
        try
        {
            //doing something
            s.append("Word");
 
            return s;
        }catch(Exception e){
            return s;
        }finally{
            string.append("finally");
        }
    }
输出结果:HelloWordFinally

果然,finally里的修改生效,最终结果也就改变了。

3:若是finally中有return,则将会以finally中的return为准,try/catch中的return将会unreached。

public class TryTest{
    public static void main(String[] args){
        System.out.println(test());
    }
 
    private static int test(){
        int num = 10;
        try{
            System.out.println("try");
            return num += 80;
        }catch(Exception e){
            System.out.println("error");
        }finally{
            if (num > 20){
                System.out.println("num>20 : " + num);
            }
            System.out.println("finally");
            num = 100;
            return num;
        }
    }

结果为:

num>20 : 90
finally
100

可见,如果try中没有异常,那么是会顺序执行return,将值保存到临时栈中,然后执行finally,如果finally中有return,此时会覆盖try中的返回值。

你可能感兴趣的:(return 和 finally究竟谁先被执行?)