Java 多次返回:哪一个设置最终返回值?
鉴于此代码:Java 多次返回:哪一个设置最终返回值?,java,return,finally,Java,Return,Finally,鉴于此代码: String test() { try { return "1"; } finally { return "2"; } } 语言规范是否定义了调用test()的返回值?换句话说:在每个JVM中都是一样的吗 在Sun JVM中,返回值是2,但我想确定,这不依赖于VM。是的,定义“2”是结果。如果一个虚拟机做的不同,它就不符合规范 大多数编译器都会对此抱怨。例如,Eclipse将声明永远不会执行返回块,但这是错误的 编写这样的代
String test() {
try {
return "1";
} finally {
return "2";
}
}
语言规范是否定义了调用test()
的返回值?换句话说:在每个JVM中都是一样的吗
在Sun JVM中,返回值是2
,但我想确定,这不依赖于VM。是的,定义“2”是结果。如果一个虚拟机做的不同,它就不符合规范
大多数编译器都会对此抱怨。例如,Eclipse将声明永远不会执行返回块,但这是错误的
编写这样的代码是非常糟糕的做法,千万不要这样做:)除以下示例外,finally块将始终执行:
String test() {
try {
System.exit(0);
} finally {
return "2";
}
}
在这种情况下,JVM将停止,而不执行finally
块
因此,在您的示例中,返回值将是
2
是,如果您从finally
块返回了一些内容,它将替换您可能从try
或catch
块返回的任何内容
例外情况也是如此。如果在finally
块中抛出某个异常,该异常将替换try
或catch
块中抛出的任何异常。因此,请注意不要在finally
块中抛出某些内容,因为它可能隐藏失败的原始原因。是的,Java语言规范对此问题非常清楚():
带有finally块的try语句通过首先执行try块来执行。还有一个选择:
- 如果try块的执行正常完成,[…]
- 如果try块的执行由于抛出值V而突然完成,[…]
- 如果try块的执行由于任何其他原因而突然完成,则执行finally块。还有一个选择:
- 如果finally块正常完成,[…]
- 如果finally块因原因S而突然完成,则try语句因原因S而突然完成(并且原因R被丢弃)。
你可以参考下面的链接。我希望它能提供所有细节:
它说,即使try或catch块有return语句,finally块也将始终执行。如果finally块也有return语句,那么这将覆盖try或catch块内的return语句,在这种情况下,try/catch中抛出的任何异常都将被丢弃(错误方法)。读取程序字节码后,代码如下所示: 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";
}
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";
}
和程序:带捕捉块:
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"; //temporary variable
System.out.println("finally");
return "2";
Exception exception;
exception;
System.out.println("finally");
return "2";
}
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";
}
注意:使用JDK1.7编写,使用Cavaj反编译。以上答案总结得很好,只想在这里补充一点
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
另一件有趣的事情是,如果最终使用
return
返回某个内容,则任何抛出的异常都将被丢弃。“throw e”永远无法访问。千万不要这样做,显然大学教授真的很喜欢编写这样的代码,尽管你已经回答了10年了