【问题标题】:try/catch block return with finally clause in java [duplicate]java中带有finally子句的try / catch块返回[重复]
【发布时间】:2013-11-22 19:54:58
【问题描述】:

鉴于 java 中的以下 try/catch 块:

try{
  return;
}
catch(SomeException e){
  System.out.println(e);
}
finally{
  System.out.println("This is the finally block");
}

根据这篇文章:“Does finally always execute in Java?”我可以看到程序的输出将是“这是 finally 块”。但是,我无法弄清楚这是怎么可能的,因为 print 语句前面有一个 return ...

我怀疑这种行为与线程有关,但我不确定。请赐教。谢谢。

【问题讨论】:

  • 该问题的第三个答案详细解释了它。

标签: java return try-catch try-catch-finally


【解决方案1】:

finally 在return 语句之前执行。由于 java 规则 finally 将始终执行,除非 JVM 崩溃或调用 System.exit()。

Java语言规范明确提到finally在不同条件下的执行:

http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.2

【讨论】:

  • 文档声明“如果方法或构造函数中有任何 try 语句,其 try 块包含 return 语句,则这些 try 语句的任何 finally 子句将按从内到外的顺序执行,在将控制权转移到方法或构造函数的调用者之前”。如果我将 try 块中的代码更改为 return 0;,那么我的控制台将打印“这是 finally 块”,然后是 0。但是,如果我在 return 0; 之前放置一个打印语句,那么顺序将是 - 新的 try块打印语句,'这是 finally 块',然后是 0。我很困惑
【解决方案2】:

return 语句对finally 块的执行没有影响。不执行finally 块的唯一方法是如果JVM 在执行finally 块之前崩溃/退出。检查此Link 了解更多信息。所以,如果你的代码被替换为

try{
  System.exit(0);
}
catch(SomeException e){
  System.out.println(e);
}
finally{
  System.out.println("This is the finally block");
}

finally 块不会执行

【讨论】:

    【解决方案3】:

    六月是正确的。我还想注意从 finally 块中抛出异常,它们会增加其他发生的异常。例如(有点愚蠢的例子,但它说明了重点):

    boolean ok = false;
    try {
       // code that might throw a SQLException
       ok = true;
       return;
    }
    catch (SQLException e) {
       log.error(e);
       throw e;
    }
    finally {
       if (!ok) {
          throw new RuntimeException("Not ok");
       }
    }
    

    在这种情况下,即使捕获并重新抛出 SQLException,最终也会在此处抛出 RuntimeException,它会“屏蔽”或覆盖 SQLException。调用者将收到 RuntimeException 而不是 SQLException。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-28
      • 2011-06-01
      • 2015-09-05
      • 1970-01-01
      • 2014-04-27
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      相关资源
      最近更新 更多