【JAVA】当finally遇上return

版权声明:转载请注明 https://blog.csdn.net/qq_33591903/article/details/83719608

                                       当finally遇上return 

刚学异常捕获机制时,会有这么一个问题,当try中出现return语句时,那么finally语句还会不会执行呢?

先从一道代码题入手,那么该段代码的输出是什么呢?

 public static int testFinally1() {
        int i = 0;
        try {
            ++i;
            return i;
        } catch (Exception e) {
            ++i;
            return i;
        } finally {
            System.out.println("finally");
        }
    }

输出结果截图

可以看得出,try语句块中即使有了return语句,finally也照样执行了,但从执行的结果来看,finally先执行,然后再执行return 0的语句。

由此道题总结出一下两点:

(1)在java的异常捕获机制中,finally的语句块保证了不管遇到什么情况,finally语句块一定被执行,除非突然出现崩溃或者是System.exit(),这两种情况不谈,太特殊了。

(2)当程序执行到return语句中,就意味着结束对当前函数的调用并跳出这个函数体,任何语句要执行都只能在return前执行,因此finally语句块中代码也是在return前执行的。

从深层理解来看,当执行到try中的return语句时,return关键词会先把i放入到一个临时的栈空间中,然后再去执行finally中的语句,执行完毕后,再把临时栈空间中的值返回。


如果在finally中修​​​​​​改i的值呢?

public static int testFinally1() {
        int i = 0;
        try {
            ++i;
            return i;
        } catch (Exception e) {
            ++i;
            return i;
        } finally {
            ++i;
            System.out.println("finally");
        }
    }

按理说,应该返回2啊,可事实的返回结果为:

刚才解释过,只有return才会把i的值放入到临时的栈空间中,执行try中return i时,return将i的值,也就是1放入到栈空间中,finally执行时,i的值确实等于2,但是没有更新到临时的栈空间中,finally执行完后,返回栈空间中的值,也就是1.


如果在finally语句块中return i呢?

 public static int testFinally1() {
        int i = 0;
        try {
            ++i;
            return i;
        } catch (Exception e) {
            ++i;
            return i;
        } finally {
            ++i;
            System.out.println("finally");
            return i;
        }
    }

返回结果:

这是由于执行到finally中的return时,导致栈空间中的值被及时更新了,导致返回的结果是2。

但是这仅仅局限于基本数据类型,简单的理解为对于基本数据类型的变量,finally语句中的return会覆盖try中的return


那么对于引用类型呢?注意我没在finally中返回。

    public static StringBuilder testFinally2() {
        StringBuilder sb = new StringBuilder();
        try {
            sb.append("a");
            return sb;
        } catch (Exception e) {
            sb.append("b");
            return sb;
        } finally {
            System.out.println("finally");
            sb.append("c");
        }
    }

输出结果:

从这里可以分析出,try中的return把sb这个变量引用而不是把“a"存入临时的栈空间中了,那么在finally中即使没有更新栈空间的情况下,返回的值也是最新的值,即“ac”。

那么,可以总结一下,对于基本数据类型的变量,临时栈空间中直接存的就是具体的一个值。而对于引用变量,栈空间存放的是这个引用变量,而非具体的一个值。

猜你喜欢

转载自blog.csdn.net/qq_33591903/article/details/83719608