在Try Catch Finally中Return
前两天被问到一个问题:“如果在try中return了,那么finally里面的代码还会执行吗?”
这个问题并不难,答案是肯定的,会执行,因为finally是无论try还是catch执行完,都会执行的。
然而相对的,我想到了另外一个问题:“先执行return还是先执行finally?”
看一个例子:
public class FinallyReturnTest {
public static void main(String[] args) {
System.out.println("return value is: " + returnValueTest());
}
public static int returnValueTest() {
int a = 0;
try {
return ++a;
} catch (Exception e) {
} finally {
++a;
}
}
}
上面代码的运行结果,会是1还是2?(吐槽下:希望别有人觉得是0…)
答案大家最好还是去尝试一下,不过我还是告诉大家:答案是1。
为什么是1我就不详细讲了,大家去单步一下,一目了然。因为是先return之后,才执行的finally中的++a,所以finally中的++a只是改变了returnValueTest()方法中的a的值,而没有改变改函数的return值。
之后,我又扩展性的想到了这样一个问题:如果try和finally中都return,那么结果会是哪个?(我发现我问题可真多啊…)
请思考如下代码:
public class FinallyReturnTest {
public static void main(String[] args) {
System.out.println("return value is: " + returnValueTest());
}
@SuppressWarnings("finally")
public static int returnValueTest() {
int a = 0;
try {
return ++a;
} catch (Exception e) {
} finally {
return ++a;
}
}
}
根据上一个问题,可见在try中的return功能是能够做到的,然而这次,return和finally都有return,会执行哪个呢?结果会是1还是2呢?
结果同样,希望大家自己单步。结果其实是2。单步可见,其实在try中的return之后,finally中的return也执行了。所以返回的内容应该是两次++a的结果——2。
我一开始是这么考虑的,这个代码是不是相当于顺序结构中写两个return?:
int a = 0;
return ++a;
return ++a;
然而,这明显不是。因为这样的代码根本不可能通过编译。于是,我想到了会不会通过内部构造一个方法实现的:
public static int returnValueTest() {
int a = 0;
return finallyTemp(a) + 1;
}
public static int finallyTemp(int a) {
return ++a;
}
如果是这样的话,解释起来就比较合理了。
然而具体底层是怎么实现,我还没有太深入研究。在这里只是把问题描述出来,给出了自己的猜想。如果大家希望求证一下,可以参考一些Java虚拟机相关内容。(当然,希望在求证之后,能够分享到博客里,并且能够给我一个链接,我会转载。)