通过阅读本论坛中已经提到的与上述主题相关的所有问题(见标题),我完全理解finally
始终被调用。 (来自System.exit
和无限循环除外)。但是,我想知道是否在catch块中调用return
,然后从finally块调用另一个return
。
例如:
public static void main(String[]args) {
int a = new TestClass().absorbeTheValue();
}
int absorbeTheValue() {
try {
int a = 10/0;
if (a > 0) return 4;
} catch(Exception e) {
return 45;
} finally {
return 34;
}
}
所以这里输出(当调用方法时)在任何情况下都是34。这意味着终于总能运行。我认为虽然其他“回归”根本没有运行。在许多帖子中,我发现最终将内容写入catch子句返回已写入的内容。我的理解是,一旦catch子句中的返回值即将被评估,控制流就会传递给finally子句,而子句又有另一个返回,这次返回将被评估,而不会将控制权传递给catch子句。通过这种方式,在运行时调用的唯一return
将是最终返回。你同意吗?
return
中的finally
不会将控件传回程序,但会返回该值并终止该方法。我们可以这样说吗?
答案 0 :(得分:93)
如果到达return
块中的try
,它会将控制转移到finally
块,并且该函数最终会正常返回(而不是抛出)。
如果发生异常,但代码从return
块到达catch
,则控制转移到finally
块,函数最终正常返回(不是抛出)
在您的示例中,return
中有finally
,因此无论发生什么情况,该函数都会返回34
,因为finally
具有最终结果(如果你愿意的话。
虽然您的示例中未涉及,但即使您没有catch
并且try
块中存在异常并且不,也会如此抓住。通过从return
块执行finally
,您可以完全禁止该异常。考虑:
public class FinallyReturn {
public static final void main(String[] args) {
System.out.println(foo(args));
}
private static int foo(String[] args) {
try {
int n = Integer.parseInt(args[0]);
return n;
}
finally {
return 42;
}
}
}
如果你在没有提供任何参数的情况下运行它:
$ java FinallyReturn
... foo
中的代码会引发ArrayIndexOutOfBoundsException
。但由于finally
块执行return
,该异常会被抑制。
这就是为什么最好避免在return
中使用finally
的原因之一。
答案 1 :(得分:67)
以下是一些显示其工作原理的代码。
class Test
{
public static void main(String args[])
{
System.out.println(Test.test());
}
public static String test()
{
try {
System.out.println("try");
throw new Exception();
} catch(Exception e) {
System.out.println("catch");
return "return";
} finally {
System.out.println("finally");
return "return in finally";
}
}
}
结果是:
try
catch
finally
return in finally