根据答案here ,
据说如果我们在 try/catch block 中有 return 语句,那么在执行 return 语句之前,finally block 将被执行。
但我看到以下代码的一些意外输出:
Output
In try block, value is : 20
In finally block, value is : 40
In main method, value is : 20
在从 try block 返回值之前,'x' 的值在 finally 中设置为 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());
}
这描述了in JLS 14.20.2 , "try-finally 和 try-catch-finally 的执行":
A try statement with a finally block is executed by first executing the try block. Then there is a choice:
- If execution of the try block completes normally, then the finally block is executed, and then there is a choice:
您的 try block 没有正常完成,它在 return
时突然完成,所以这不适用。
- If execution of the try block completes abruptly because of a throw of a value V, then there is a choice:
你不抛出,所以这也不适用。
- If execution of the try block completes abruptly for any other reason R, then the finally block is executed, and then there is a choice:
这适用。
- If the finally block completes normally, then the try statement completes abruptly for reason R.
您的 finally block 正常完成(您不会从 finally 返回或抛出 - 这样做是不好的做法),因此您的 try 语句因 R 的原因而完成。
那个R就是你在return语句的表达式求值的时候返回了x
的值。
您可以在 JLS 14.17 中找到它:
A return statement with an Expression attempts to transfer control to the invoker of the method or lambda body that contains it; the value of the Expression becomes the value of the method invocation. ... If evaluation of the Expression completes normally, producing a value V, then the return statement completes abruptly, the reason being a return with value V.
您随后覆盖它并不重要:R(“返回值 V”)在执行 finally 之前确定的原因,所以这也是 finally block 也突然完成的原因。