首页 文章

Try-catch-finally-return澄清[重复]

提问于
浏览
55

这个问题在这里已有答案:

通过阅读本论坛中已经提到的与上述主题相关的所有问题(见 Headers ),我完全理解 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 . 这意味着终于总能运行 . 我想虽然其他"returns"根本没有运行 . 在很多帖子中,我发现最后将内容写入catch子句返回已写入的内容 . 我的理解是,一旦catch子句中的返回值即将被评估,控制流就会传递给finally子句,而子句又有另一个返回,这次返回将被评估,而不会将控制权传递给catch子句 . 通过这种方式,在运行时调用的唯一 return 将是最终返回 . 你同意吗?

finally 中的 return 不会将控件传回给程序,但会返回该值并终止该方法 . 我们可以这样说吗?

2 回答

  • 91

    如果到达 try 块中的 return ,它会将控制权转移到 finally 块,并且该函数最终会正常返回(而不是抛出) .

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

    在您的示例中, finally 中有 return ,因此无论发生什么情况,该函数都将返回 34 ,因为 finally 具有最终(如果您愿意)单词 .

    尽管未在您的示例中介绍,但即使您没有 catch 并且如果在 try 块中抛出异常而未捕获异常,也会如此 . 通过从 finally 块执行 return ,可以完全禁止异常 . 考虑:

    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 ,该异常会被抑制 .

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

  • 66

    以下是一些显示其工作原理的代码 .

    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
    

相关问题