请参阅以下代码并解释输出行为。
public class MyFinalTest {
public int doMethod(){
try{
throw new Exception();
}
catch(Exception ex){
return 5;
}
finally{
return 10;
}
}
public static void main(String[] args) {
MyFinalTest testEx = new MyFinalTest();
int rVal = testEx.doMethod();
System.out.println("The return Val :"+rVal);
}
}
结果是返回Val:10。
Eclipse显示警告:finally block does not complete normally。
catch块中的return语句会发生什么?
可能重复为什么在finally块中更改返回的变量不会更改返回值?
一个非常受欢迎的面试问题
它被finally中的一个覆盖,因为finally在其他所有内容之后执行。
这就是为什么,一个经验法则 - 永远不会从finally返回。例如,Eclipse显示了该片段的警告:"finally块无法正常完成"
始终执行finally(唯一的例外是System.exit())。你可以这样想到这种行为:
抛出异常
捕获异常并将返回值设置为5
最后执行块,返回值设置为10
该函数返回
try / catch块的一般规则:1)永远不要在finally块中返回一个值。 2)避免在finally或者黑色中抛出异常,因为它会掩盖原始异常。
说最后总是执行是一件非常危险的事情。 你真的不能依赖它执行任务关键操作。 考虑像停电,jvm腐败/崩溃等等。我知道这听起来有点挑剔,但总是一个强有力的词,我想我们有时会忘记我们生活在现实世界中那样的灾难 发生。
如果您记住VM的低级布局,这是一个简单的问题。
返回值由catch代码置于堆栈中。
然后,执行finally代码并覆盖堆栈上的值。
然后,该方法返回最新的值(10)以供调用者使用。
如果不确定这样的事情,请回到您对底层系统的理解(最终进入汇编程序级别)。
(有趣的旁注)
最后块总是被执行,除非并且直到System.exit()语句是finally块中的第一个。所以在上面的示例中,exe语句被try语句抛出并在catch块中获取catch。存在值为5的return语句,因此在堆栈调用值5中稍后添加最终块执行并且最新返回值在返回值时添加到堆栈顶部,堆栈按照堆栈行为返回最新值"LAST IN FIRST OUT"所以它将返回值为10。
始终执行finally块(如果执行了匹配的尝试),所以在方法返回5之前??,如catch块中一样,它执行finally块并返回10。
finally部分将执行始终执行。例如如果你有任何事情要发布,或者注销某种事情,如果发生错误,那么去catch部分,最后将执行。
Session session // opened some session
try
{
// some error
}
catch { log.error }
finally
{ session.logout();}
它不应该用于返回任何东西。你可以在外面使用。