当return遇到finally
文章导读
上一篇文章《Java finally语句到底是在return之前还是之后执行?—第一篇》通过执行代码来验证了try/catch/finally中包含return的各种情况,得出的结论是:
- finally语句在try和catch语句中的return执行后、返回前执行;
- 若finally语句中没有return,则其执行结果不影响try和catch中已确定的返回值;
- 若finally语句中有return,则其执行后的结果会直接返回。
在这篇文章中,我们换个角度,通过查阅其oracle java 官方文档来加深理解。
打开《oracle java官方文档》 的相应有关finally的说明,找到英文说明:
The finally Block
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.
Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
翻译如下:
当try语句退出时肯定会执行finally语句。这确保了即使发了一个意想不到的异常也会执行finally语句块。但是finally的用处不仅是用来处理异常——它可以让程序员不会因为return、continue、或者break语句而忽略了清理代码。把清理代码放在finally语句块里是一个很好的做法,即便可能不会有异常发生也要这样做。
注意,当try或者catch的代码在运行的时候,JVM退出了。那么finally语句块就不会执行。同样,如果线程在运行try或者catch的代码时被中断了或者被杀死了(killed),那么finally语句可能也不会执行了,即使整个运用还会继续执行。
通过上面的官方说明,我们知道无论try里是否执行了return语句、break语句、还是continue语句,finally语句块还会继续执行 。同时,在 stackoverflow 里也找到了一个答案,我们可以调用 System.exit() 来终止它:
The only times finally won’t be called are:
if you call System.exit() or
another thread interrupts current one (via the interrupt method) or
if the JVM crashes first
另外,在 java的语言规范有讲到,如果在try语句里有return语句,finally语句还是会执行。它会在把控制权转移到该方法的调用者或者构造器前执行finally语句。也就是说,使用return语句把控制权转移给其他的方法前会执行finally语句。
所以,finally语句不执行的两种情况为:
1). return语句在try之前,还没执行就返回了,当然不执行。
2). try语句中用了system.exit(0)强制退出JVM,暴力退出当然也不会执行。
这也验证了上文《Java finally语句到底是在return之前还是之后执行?—第一篇》通过测试得出的结论。