我有以下代码 .
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
现在我明白了,除非我们调用system.exit(0),否则最终总会被执行;调用或JVM崩溃 . 我无法理解的是为什么返回值已经改变了?我仍然希望它返回try块的值 .
任何人都可以解释为什么最终值被考虑而不是try块的返回值?
Please refrain from answering because finally is executed even if there is an return in try block ... or finally doesn't execute only if there is a system.exit(0); called or the JVM crashes. as I know that.
编辑:
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
3 回答
就在从主块返回之前,JVM必须确保执行
finally
块,所以它就这样做了 . 想法是执行finally
块然后返回并从主块执行return
语句 . 但是如果finally
块中有return
语句,那么它将在执行finally
块时执行...这意味着控制永远不会返回主块来完成return
语句 .JVM遇到主块中的
return
语句 . 它暂停执行主块并检查finally
子句 .它完整地执行
finally
子句,包括其return
语句 .永远不会完成
try
块 .但请注意,
try
块的return
表达式将被计算然后被丢弃 . 如果它有副作用,这很重要 . 因此,如果你的主块有return i++
,那么这对返回值没有影响,但是i
仍然会增加 . (感谢Dirk指出这一点 . )If you have return in finally, that's the final return.
这并不奇怪 . 这是实际行为 . 返回值在
finally
块决定 .如果你最后没有返回任何东西,那么前一个返回值的值就是返回值(在你的情况下,是try块值) .
无论你在
try
做什么,即使你从你的try块返回,finally块总是会执行(如果你最后返回,那就是最后的返回) .来自finally docs
注意:最终设计为清理 .
在Java中,代码:
将由编译器重写为:
基本上,编译器将在每个执行路径中复制
finally
块中的代码一次,这将导致代码执行离开受保护的块,无论是通过return
,throw
还是直通 . 请注意,虽然某些语言不允许在finally
块中使用return
,但Java不会;但是,如果由于异常而执行了finally
块,则块内的return
可能导致异常被静默放弃(查看上面标记为"Finally code executed before re-throw"的代码;如果return 3;
执行,则重新抛出将被跳过) .