Try-catch-finally-return 澄清

2022-01-19 00:00:00 return try-catch java finally

通过阅读本论坛中与上述主题相关的所有问题(见标题),我完全理解 finally 总是被调用.(除了 System.exit 和无限循环).但是,我想知道是否在 catch 块中调用了 return,然后从 finally 块中调用了另一个 return.

By reading all the questions already asked in this forum related to the topic above (see title), I thoroughly understand that finally gets always called. (except from System.exit and infinite loops). However, I would like to know if a return is called in a catch block and then another return is called from the finally block.

例如:

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.这意味着 finally 总是运行.我认为虽然其他回报"根本没有运行.在许多帖子中,我发现最终将内容写入 catch 子句返回已经写入的内容.我的理解是,一旦 catch 子句中的返回值即将被评估,控制流就会传递给 finally 子句,该子句又会返回另一个返回值,这一次将评估返回值,而不会将控制权传递回 catch 子句.这样,在运行时调用的唯一 return 将是 finally 返回.你同意吗?

So here the output (when the method is called) is going to be 34 in any case. It means that finally always gets run. I think though that the other "returns" are not run at all. In many posts I found the fact that finally write the content over what had been already written by the catch clause return. My understanding is that as soon as the return value in the catch clause is about to be evaluated, the control flow pass to the finally clause which having in turn another return, this time the return will be evaluated without passing control back to the catch clause. In this way the only return called at runtime will be the finally return. Do you agree with that?

return 不会将控制权传递回程序,而是返回值并终止方法.我们可以这样说吗?

A return in finally does not pass back the control to the program but returns the value and terminates the method. Can we say so?

推荐答案

如果 try 块中的 return 到达,则将控制权移交给 finally 块,函数最终正常返回(不是 throw).

If the return in the try block is reached, it transfers control to the finally block, and the function eventually returns normally (not a throw).

如果发生异常,但随后代码从 catch 块到达 return,控制将转移到 finally 块,然后函数最终正常返回(不是抛出).

If an exception occurs, but then the code reaches a return from the catch block, control is transferred to the finally block and the function eventually returns normally (not a throw).

在您的示例中,您在 finally 中有一个 return,因此无论发生什么,该函数都将返回 34,因为finally 有最后的(如果你愿意的话)字.

In your example, you have a return in the finally, and so regardless of what happens, the function will return 34, because finally has the final (if you will) word.

虽然您的示例中没有涉及,但即使您没有 catch 并且如果在 try 块和 没有抓到.通过从 finally 块执行 return,您可以完全抑制异常.考虑:

Although not covered in your example, this would be true even if you didn't have the catch and if an exception were thrown in the try block and not caught. By doing a return from the finally block, you suppress the exception entirely. Consider:

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;
    }
  }
}

如果你在不提供任何参数的情况下运行它:

If you run that without supplying any arguments:

$ java FinallyReturn

...foo 中的代码抛出 ArrayIndexOutOfBoundsException.但是因为 finally 块做了一个 return,所以该异常被抑制了.

...the code in foo throws an ArrayIndexOutOfBoundsException. But because the finally block does a return, that exception gets suppressed.

这是最好避免在 finally 中使用 return 的原因之一.

This is one reason why it's best to avoid using return in finally.

相关文章