先看两端代码,猜测一下结果
代码一:
public static int test1() {
int x = 1;
try {
return x;
} finally {
x = 2;
}
}
代码二:
public static int test2() {
int x = 1;
try {
return x;
} finally {
x = 2;
return x;
}
}
结果是,代码一返回的是1,代码二返回的是2
原因:有一个 临时存储变量
- 在try中return的话,会吧return的值存储进临时存储变量中,然后在执行finally,最后返回的是临时变量的值。。。
- 但是如果在finally中return的话,那finally的逻辑执行完才会存储进临时存储变量中,最终返回
总结:
- return的执行优先级高于finally的执行优先级,但是return语句执行完毕之后并不会马上结束函数,而是将结果保存到栈帧中的局部变量表中,然后继续执行finally块中的语句;
- 如果finally块中包含return语句,则不会对try块中要返回的值进行保护,而是直接跳到finally语句中执行,并最后在finally语句中返回,返回值是在finally块中改变之后的值;
finally中的代码一定会执行,也有例外
在正常情况下,它是一定会被执行的,但是至少存在以下三种情况,是一定不执行的:
try语句没有被执行到就返回了,这样finally语句就不会执行,这也说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到;
try代码块中有System.exit(0);这样的语句,因为System.exit(0);是终止JVM的,连JVM都停止了,finally肯定不会被执行了;
守护线程会随着所有非守护线程的退出而退出,当守护线程内部的finally的代码还未被执行到,非守护线程终结或退出时,finally 肯定不会被执行;