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

Posted

技术标签:

【中文标题】Try-catch-finally-return 澄清 [重复]【英文标题】:Try-catch-finally-return clarification [duplicate] 【发布时间】:2013-02-19 23:21:25 【问题描述】:

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

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

【问题讨论】:

请缩进你的代码。 另见:***.com/questions/65035/… 你有什么问题?? 【参考方案1】:

如果到达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 的原因之一。

【讨论】:

重要的是要注意throw 将与return 互换用于这些目的。 (例如,throw new Exception(4)throw new exception(34) 我只是想了解一下 user1442960 所说的话。 JLS 没有提到 catch 或 finally 中的返回。它使用了“突然”一词,我猜这意味着异常或返回。 @Steve11235:不,来自catch 块的return 将“正常”完成,而不是“突然”完成。这一点从Section 11 中可以很清楚地看到:“在抛出异常的过程中,Java 虚拟机会突然完成任何表达式、语句、方法和构造函数调用、初始化程序和字段初始化表达式在当前线程中开始但未完成执行。”【参考方案2】:

这里有一些代码说明它是如何工作的。

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

【讨论】:

+1 易于理解并教会了我一些新东西:) @LoganDam T.J.克劳德给出了很好的解释。 @LoganDam:这是对操作顺序的一个很好的清晰解释。但是,它没有回答所提出的问题。该问题明确询问当 finally 块包含 return 语句时会发生什么。 @unholysampler 很好,我更新了答案。谢谢。 我又学到了一些新东西……继续加油!

以上是关于Try-catch-finally-return 澄清 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

C#常见面试题——try-catch-finally-return