我有以下一段代码。
public static void main(String[] args) {
System.out.println(returnString());
}
private static String returnString(){
try {
System.out.println("Executing try");
return "Return try value";
} catch (Exception e){
System.out.println("Executing Catch");
return "Return catch value";
} finally {
System.out.println("Executing finally");
return "Return finally value";
}
}
其输出为
Executing try
Executing finally
Return finally value
如果我将我的finally块更改为不返回任何类似的内容
public static void main(String[] args) {
System.out.println(returnString());
}
private static String returnString(){
try {
System.out.println("Executing try");
return "Return try value";
} catch (Exception e){
System.out.println("Executing Catch");
return "Return catch value";
} finally {
System.out.println("Executing finally");
}
}
然后输出为
Executing try
Executing finally
Return try value
现在我明白了finally总是被执行的,除非我们调用system.exit(0);调用或JVM崩溃。我不明白的是,为什么返回值发生了变化?我仍然希望它返回try块的值
有人能解释为什么要考虑finally值而不是try块的返回值吗?
请不要回答,因为即使try块中有返回,finally也会执行。。。或者只有当存在系统时才最终不执行。exit(0);调用或JVM崩溃。正如我所知
编辑:
(根据Dirk对此的评论)
public static void main(String[] args) {
System.out.println(returnString());
}
private static String returnString(){
try {
System.out.println("Executing try");
return printString("Return try value");
} catch (Exception e){
System.out.println("Executing Catch");
return printString("Return catch value");
} finally {
System.out.println("Executing finally");
return printString("Return finally value");
}
}
private static String printString(String str){
System.out.println(str);
return str;
}
输出:
Executing try
Return try value
Executing finally
Return finally value
Return finally value
就在从主块返回之前,JVM必须确保finally
块已执行,因此它会执行此操作。其思想是执行finally
块,然后返回并从主块执行return
语句。但是,如果在finally
块中有一个return
语句,那么它将在执行finally
块时执行。。。这意味着控制永远不会返回到主块以完成CCD_ 7语句。
- JVM在主块中遇到
return
语句。它暂停主块的执行并检查finally
子句 - 它完整地执行
finally
子句,包括它的return
语句 - 因此,它从未完成
try
块
然而,请注意,try
块的return
表达式被求值,然后被丢弃。如果它有副作用,这一点很重要。因此,如果你的主块有return i++
,那么这对返回值没有影响,但i
仍然会增加。(感谢Dirk指出这一点。)
如果您最终返回,那就是最终返回
这并不奇怪。这是实际行为。返回在finally
块中决定的值。
如果您在finally中没有返回任何内容,则返回值的前一个值就是返回值(在您的情况下,是try块值)。
不管你在try
中做什么,finally块总是执行,即使你从try块返回(如果你最终返回,那就是最终返回)。
来自finally
文档
运行时系统始终执行finally块中的语句,而不管在try块中发生了什么。所以这是进行清理的最佳场所。
注:最后设计为清理。
在Java中,代码:
try {
if (foo()) return 1;
} catch (Exception e){
if (goo()) return 2;
} finally {
if (moo()) return 3;
}
将由编译器重写为:
try {
if (foo())
{
if (moo()) return 3; // Finally code executed before return
return 1;
}
} catch (Exception e){
if (goo())
{
if (moo()) return 3; // Finally code executed before return
return 2;
}
} catch (Throwable e){
if (moo()) return 3; // Finally code executed before re-throw
throw e;
}
if (moo()) return 3; // Finally code executed before leaving block
基本上,编译器将在每个执行路径中复制finally
块中的代码一次,这将导致代码执行离开保护块,无论是通过return
、throw
还是失败。请注意,虽然某些语言不允许在finally
块内使用return
,但Java不允许;但是,如果由于异常而执行了finally
块,则该块中的return
可能会导致异常被静默放弃(请参阅上面标记为"重新抛出前最后执行的代码"的代码;如果执行return 3;
,则会跳过重新抛出)。