我在java认证网站上找到了这段代码
public class Test1{
public static void main(String args[]){
System.out.println(method());
}
public static int method(){
try{
return 1;
}
catch(Exception e){
return 2;
}
finally{
return 3;
}
}
}
因此这段代码的输出显示为3。 这怎么可能..因为它在try块本身返回1? 代码永远不会最终到达??
答案 0 :(得分:2)
代码永远不会最终到达吗? 不,如果有一个finally块控件将在try或/和catch
之后终止因为无论如何最终总会执行。除了Mike Kobit说System.exit
感谢 Jason C ,来自JLS 14.17. The return Statement
然后可以看出,return语句总是突然完成。
前面的描述说“尝试转移控制”而不仅仅是“转移控制”,因为如果在try块或者catch子句包含return语句的方法或构造函数中有任何try语句(§14.20),那么任何最终在将控制权转移给方法或构造函数的调用者之前,这些try语句的子句将按顺序执行,最内层到最外层。突然完成finally子句可能会破坏由return语句启动的控制权转移。
来自JLS 14.20.2. Execution of try-finally and try-catch-finally
如果try块的执行正常完成,则执行finally块,然后有一个选择:
- 如果finally块正常完成,则try语句正常完成。
- 如果finally块因原因S而突然完成,那么try语句会因为S而突然完成。
醇>
所以在你的代码中try返回1,然后控制转到finally,返回3.所以函数的返回值为3。
答案 1 :(得分:2)
正如Sumit Singh在他的回答中提到的,这是因为return
导致方法突然结束。
当您在try-catch-finally块中抛出新的异常时,您可以观察到相同的行为,因为throw
也是abrupt。
请参阅以下代码:
public class FinallyTest {
public static void main(String[] args) {
abrupt();
}
@SuppressWarnings("finally")
public static void abrupt() {
try {
throw new IllegalArgumentException("In Try");
}
catch(Exception x) {
throw new IllegalArgumentException("In Catch");
}
finally {
throw new NullPointerException("In Finally");
}
}
}
运行代码时,控制台显示
Exception in thread "main" java.lang.NullPointerException: In Finally
at FinallyTest.abrupt(FinallyTest.java:15)
at FinallyTest.main(FinallyTest.java:3)
即使你在IllegalArgumentException
块中抛出一个新的try
,也只会抛出NullPointerException
块中的finally
,因为这个块突然结束了。
答案 2 :(得分:0)
最后,块将始终在执行return
语句之前执行。 (有一些例外,例如JVM本身崩溃或system.exit()
被调用)
原因如下:
我们通常最终使用我们的资源或清理。现在,如果开发人员在try块中意外地写入return语句,那么逻辑上最终将永远不会执行。为了解决这个问题,JVM本身处理这个场景并在从try块返回之前执行finally块。
请记住,当try块退出时,finally块始终执行。以上解释的场景也适用于返回,继续或中断。
答案 3 :(得分:-2)
因为如果我们考虑优先级finally
超过try
或catch
,那么要明确如果异常没有捕获到什么,那么最终执行,这里是在一个方法内部工作,所以当一个方法假设返回一个输出int
值时,它显然会始终从finally
返回值。
有意义吗?