try-catch-finally是用来捕获异常的,其中finally不管是try或者是catch中有没有异常,最后大概率都是会执行的,这是因为编译器会将finally块中的代码复制成两份,分别添加在try和catch的后面,但是如果try或者catch中出现了return语句,情况就会不一样。下面我们就来看一下这种情况。
1、finally中没有return语句
int i = 1;
try {
i = 2;
return i;
} catch (Exception e) {
} finally {
i = 3;
}
最后的返回值是2
2、finally中有return语句
int i=1;
try {
i = 2;
return i;
} catch (Exception e) {
} finally {
i = 3;
return i;
}
最后的返回值是3
上面两个代码只是在finally中是否存在return语句的区别,但是结果却是不一样的。
可以看到如果finally中没有return语句,程序就会把finally中的操作数据忽略掉,其实finally中的数据操作是执行的,但是并没有返回,所以给我们的感觉是像没有操作一样。return语句返回之前,虚拟机会将待返回的值压入操作数栈,等待返回,即使finally语句对i进行了修改,但是待返回的值已经确实存在于操作数栈中,所以不会影响程序返回结果。在try中的数据处理完,如果检测到有try中有return语句时,会先将数据压入操作数栈等待返回,然后去执行finally语句,如果finally语句没有将新的结果压入操作数栈中,那么只能返回原先的结果2。
从这个角度理解,即使finally中对数据处理,但是返回的依旧是try中的“脏数据”(过时的数据)
也就是说finally并不是没有执行,而是执行了却没有返回。如果在finally中添加return语句会将finally处理过的数据压入操作数栈返回,原先的“脏数据”失效。所以返回的是3