加载中...

try中有return语句,finally还会执行吗?


try中有return语句,finally还会执行吗?

先说结论,是可以执行的

我们来看看实际的实验结果

实验一

假设我们有这样一个代码块:

int x = 1;
try {
    ++x;
    return x;
} catch (Exception e){
    e.printStackTrace();
}finally {
    System.out.println(x);
}
System.out.println(x);
return x;

你们认为会执行打印语句么?

没错,这个代码块是会执行finally里面的打印语句的,结果就如下所示:

实验二

现在我们稍微改改上面的代码

int x = 1;
try {
    ++x;
    return x;
} catch (Exception e){
    e.printStackTrace();
}finally {
    x = 3
}
return x;

-----------------------------------------
//这里是在返回后的主函数内打印
System.out.println(x);

现在我们不在finally里面打印,而是返回到主函数后再打印,那么结果是是什么呢?

我想应该有很多读者和我最初的想法一样:“既然finally语句会执行,那么最后返回的x值当然是3了呀!”如果是这样的想法,那么恭喜你,你也回答错了,其实这段代码打印的结果是2

为什么返回到主程序的值会是2呢?其实在JVM规范里面明确说明了这种情况:

If the try clause executes a return, the compiled code does the following:

  1. Saves the return value (if any) in a local variable.
  2. Executes a jsr to the code for the finally clause.
  3. Upon return from the finally clause, returns the value saved in the local variable.

也就是说,try中有return的时候的执行顺序大概如下:

1、先把要return的x值保存下来

2、执行finally语句块内的代码

3、返回第一步保存下来的x值

这么一看,也就清晰明白了为什么上面的返回值为2

还有一种特别的情况,假设finally语句块内又有一个return语句:

int x = 1;
try {
    ++x;
    return x;
} catch (Exception e){
    e.printStackTrace();
}finally {
    x = 3;
    return x;
}

-----------------------------------------
//这里是在返回后的主函数内打印
System.out.println(x);

那么此时的结果又是什么呢?

可以看到,此时的打印结果返回了3,也就是说,真正的返回语句是finally语句块内的return,前面try语句块中的return被丢弃了。

小结

从上面的实验来看,可以得到相关的结论为:

  1. try中有return, 会先将值暂存,无论finally语句中对该值做什么处理,最终返回的都是try语句中的暂存值。
  2. 当try与finally语句中均有return语句,会忽略try中return,真正的返回值为finally里面的return。

文章作者: DestiNation
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 DestiNation !
  目录