Java中的try, finally, return的执行顺序

时间:2021-02-02 18:23:38

最近得准备各种笔试, 看了几道道关于try,catch,finally,return语句之间的执行顺序的题目,   本来自以为已经理解了finally的作用, 结果还是做错了, 这里做个笔记总结备忘。


先看一个喜闻乐见的普通例子:

/**
* @author csdn libertine1993
*/
public class Test{
public static void main(String[] args){
System.out.println(test());
}
public static int test(){
int b = 23;
try{
b = 88;
}
finally{
b = 999;
}
return b;
}
}

输出为:999
Java中的try, finally, return的执行顺序

分析: 没什么特别之处, 顺序执行try, catch, finally后b = 999, 返回并输出.


接着我们来看比较值得考虑的一种情况,当return语句出现在try语句块的时候, 是先执行try块的return呢,还是先执行finally呢. 看个例子

/**
* @author csdn libertine1993
*/
public class Test{
public static void main(String[] args){
System.out.println(test());
}
public static int test(){
int b = 23;
try{
return b = 88;
}
finally{
b += 100000;// try to change b in finally block
}
}
}
输出为:88

Java中的try, finally, return的执行顺序

分析: 先给出结论, return语句的操作会先被执行, 得到返回值保存于缓存中, 再执行finally块的内容, 再读取缓存的返回值返回。

try语句块中出现了return b = 88 语句的时候, 实际上是先执行了b = 88, 作为返回值,但是接着并没有马上返回而是将返回值88保存起来, 然后去执行finally的内容, 执行完finally之后, 返回返回值, 退出函数。虽然finally块改变了b的值, 但是返回值已经在try块中缓存为88, 返回的还是缓存的88.


那么如果在finally中也有return语句会怎么样呢?

/**
* @author csdn libertine1993
*/
public class Test{
public static void main(String[] args){
System.out.println(test());
}
public static int test(){
int b = 23;
try{
return b = 88;
}
finally{
b += 100000;
return b;// the return statement in finally block will cover the return result of the try block
}
}
}

输出为:100088

Java中的try, finally, return的执行顺序

分析: 在执行到finally块的return之前,分析过程同上。 在finally块的return语句更新了缓存的88为100088, 再退出函数。


总结: try语句块中的return语句内的操作会在finally块执行之前执行(第二个例子的b = 88), 但是返回的操作是在finally块之后才发生的。 如果finally块内也有return语句, 那么返回的值会被finally块的return覆盖。


写在最后: 如果有兴趣深入可以阅读JVM相关书籍, 查看编译出来的字节码, 由于时间有限,这里就不深入讨论。