Java finally执行顺序

首先我们来看题
在这里插入图片描述
当做这道题时我的答案是“ABAA”。因为先执行try得到A然后执行finally 得到B 再回到try 中的return 得到A 再输出个A。但是当我看答案的时候不是这样的
正确答案是ABAB
在这里插入图片描述
因此得到一个结论
finally语句块在return语句之后,return返回值之前
看下一个例子
在这里插入图片描述
运行结果
在这里插入图片描述
由此我们可知 输出了try之后 运行了b=b+80 但是没有返回 就去执行finally 等到finally执行完以后才返回结果

例子二
在这里插入图片描述
执行结果
在这里插入图片描述
由结果可得 先执行了try 然后运行了test4,输出了return statement 返回值没有返回 去执行finally 然后返回after return
那么问题来了,如果 finally中对return的值进行修改,那么return返回来的值是修改前的还是修改后的
例子三
在这里插入图片描述
执行结果
在这里插入图片描述
可以看到没什么变化 那么我们可以得到一个结论
finally中对return的值进行了修改之后 并不会影响try中return的返回值
其实这样是不太对的 因为我们只验证了基本类型 那么下面我们验证一下引用类型来证明我们的结论是否正确
例子四
在这里插入图片描述
执行结果
在这里插入图片描述
由此看来基本类型和引用类型的结论是不同的
那么让我们总结一下吧
对于基本数据类型,finally语句块中对try语句块的return的变量进行了修改,return的则是修改前的值。
对于引用数据类型,finally语句块中对try语句块的return的变量进行了修改,return的则是修改后的值。
看到这里,不知道你有没有想到这个结论与 Java 的方法调用时的所谓的值传递和引用传递的结论有些类似。
既然得出了这个结论,那么这个结论是必然的情况么?一定正确么?别急,来看下一个例子。
例子五
在这里插入图片描述
执行结果
在这里插入图片描述
看到这个结果是不是很震惊 为什么 推翻了上面的结论 到底是为什么呐
先说基本数据类型,由于基本数据类型是 值传递 ,所以在try里的return执行的时候,就先将变量的值隐性的作为最终返回的值。
同样的,对于引用数据类型,只是将该变量所指向的内存地址隐性的作为最终返回的值,所以即使将stu = null,也无所谓了,因为早在执行finally之前,try里的return就已经拿到了stu所指向的地址。
这里多说一句,其实 Java 里都是值传递,只不过基本数据类型的值是真正的值,而引用数据类型是地址值而已。
思考题
问:如果try与finally中都有return语句,那么到底会返回哪一个呢?
会返回finally中的return。
问:如果try里有return语句,整个try-catch-finally块之外也有一个return语句,那么哪个会执行,一定是这样么?
在try里没有发生异常的情况下,是try里的return会执行,但发生了异常,则反之。
问:如果catch中有return语句呢?当然只有在异常的情况下才有可能会执行,那么是在finally之前就返回吗?
当发生异常后,catch中的return执行情况与未发生异常时try中return的执行情况完全一样。
总结
finally 块的语句在 try 或 catch 中的 return 语句执行之后返回之前执行,且 finally 里的修改语句可能影响也可能不影响 try 或 catch 中 return 已经确定的返回值,若 finally 里也有 return 语句则覆盖 try 或 catch 中的 return 语句直接返回。

PS:本篇文章参考了一些别人的博客和观点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值