鉴于此代码:
String test() {
try {
return "1";
} finally {
return "2";
}
}
语言规范是否定义了对test()
的调用的返回值?换句话说:每个JVM中它总是一样的吗?
在Sun JVM中,返回值为2
,但我想确定,这不依赖于VM。
答案 0 :(得分:47)
是的,language spec定义结果为“2”。如果VM以不同方式执行,则不符合规范。
大多数编译器会抱怨它。例如,Eclipse将声称永远不会执行返回块,但这是错误的。
编写像这样的代码是非常糟糕的做法,不要这么做:)
答案 1 :(得分:20)
是的, Java语言规范在这个问题上非常明确(14.20.2):
首先执行try块,执行带有finally块的try语句。然后有一个选择:
- 如果try块的执行正常完成,[...]
- 如果由于抛出值V,[...]
而突然完成try块的执行- 如果由于任何其他原因导致try块的执行突然完成,则执行finally块。然后有一个选择:
- 如果finally块正常完成,[...]
- 如果finally块由于原因S而突然完成,则try语句突然完成,原因为S(并且原因R被丢弃)。
答案 2 :(得分:17)
除以下示例外,将始终执行finally块:
String test() {
try {
System.exit(0);
} finally {
return "2";
}
}
在这种情况下,JVM将停止,而不执行finally
块。
因此,在您的示例中,返回值为2
。
答案 3 :(得分:7)
是的,如果您从finally
块中返回某些内容,它将替换您从try
或catch
块中返回的内容。
例外也是如此。如果你在finally
块中抛出一些东西,该异常将替换try
或catch
块中抛出的任何异常。所以要小心不要在finally
块中抛出一些东西,因为它可能会隐藏失败的原因。
答案 4 :(得分:3)
读完程序的ByteCode后,代码如下:
finally块语句在try块的return语句之前被内联,因此finally块的返回首先执行,而原始的return语句从不执行。
对于计划:
String test() {
try {
System.out.println("try");
return "1";
} finally {
System.out.println("finally");
return "2";
}
}
转换为:
String test()
{
System.out.println("try");
String s = "1"; //temporary variable
System.out.println("finally");
return "2";
Exception exception;
exception;
System.out.println("finally");
return "2";
}
对于程序:与catch块:
String test() {
try {
System.out.println("try");
return "1";
} catch (RuntimeException e) {
System.out.println("catch");
return "2";
} finally {
System.out.println("finally");
return "3";
}
}
转换为:
String test()
{
System.out.println("try");
String s = "1";
System.out.println("finally");
return "3";
RuntimeException e;
e;
System.out.println("catch");
String s1 = "2";
System.out.println("finally");
return "3";
Exception exception;
exception;
System.out.println("finally");
return "3";
}
注意:使用JDK 1.7&使用Cavaj进行反编译。
答案 5 :(得分:0)
您可以参考以下链接。我希望它能提供所有细节:
http://www.programmerinterview.com/index.php/java-questions/will-finally-run-after-return/
它表示finally块总是会执行,即使try或catch块也有return语句。如果finally块也有return语句,那么这将覆盖try或catch块内的return语句,在这种情况下,try / catch中抛出的任何异常都将被丢弃(坏方法)。
答案 6 :(得分:0)
以上答案的总结非常好,只是想在这里再加一点。
private static int divide(int a , int b){
try{
return a/b;
}finally{
System.out.println("In finally");
return 1;
}
}
如果我们通过1,0,则上述方法将抑制它抛出的异常,并仅返回结果。 话虽如此,以上代码不应在生产环境中使用。
private static int divide(int a , int b){
int result = 0;
try{
result = a/b;
}finally{
System.out.println("In finally");
result = 1;
}
return result;
}
在finally块之后使用return语句将导致
Exception in thread "main" java.lang.ArithmeticException: / by zero