根据这里的答案, 声明如果我们在 try/catch 块中有 return 语句,那么在执行 return 语句之前,最终块将被执行。
但是我看到以下代码的一些意外输出:
输出
在 try 块中,值为 : 20
在 finally 块中,值为 : 40
在 main 方法中,值为 : 20
在从 try 块返回值之前,"x"的值最终设置为 40。但这将 x 的值返回为 20 而不是 40,以 main 方法。
有人可以解释一下,它在内部是如何工作的吗?
class ExceptionTest
{
private static int returnValue() {
int x = 10;
try {
x=20;
System.out.println("In try block, value is : " + x);
return x;
}
finally {
x = 40;
System.out.println("In finally block, value is : " + x);
}
}
public static void main (String[] args) throws java.lang.Exception
{
System.out.println("In main method, value is : " + returnValue());
}
}
这在 JLS 14.20.2 "执行 try-finally 和 try-catch-finally "中有描述:
带有 finally 块的 try 语句通过首先执行 try 块来执行。然后有一个选择:
- 如果 try 块的执行正常完成,则执行 finally 块,然后有一个选择:
您的 try 块无法正常完成,它会在return
突然完成,因此这不适用。
- 如果 try 块的执行由于抛出值 V 而突然完成,则有一个选择:
你不扔,所以这也不适用。
- 如果 try 块的执行由于任何其他原因 R 而突然完成,则执行 final 块,然后有一个选择:
这适用。
- 如果 finally 块正常完成,则 try 语句由于原因 R 而突然完成。
您的 finally 块正常完成(您不会从 finally 返回或抛出 - 这样做是不合适的做法(,因此您的 try 语句由于原因 R 而完成。
该 R 表示在计算 return 语句的表达式时返回了x
的值。
您可以在JLS 14.17中找到以下内容:
带有表达式的 return 语句试图将控制权转移给包含它的方法或 lambda 主体的调用者;表达式的值成为方法调用的值。如果表达式的计算正常完成,生成值 V,则返回语句突然完成,原因是值为 V 的返回。
随后覆盖它并不重要:原因 R("返回值 V"(是在执行 finally 之前确定的,所以这也是 finally 块突然完成的原因。