【问题标题】:Why use finally instead of code after catch [duplicate]为什么在 catch 之后使用 finally 而不是代码 [重复]
【发布时间】:2011-06-09 04:23:34
【问题描述】:

为什么这样做

} catch (SQLException sqle) {
    sqle.printStackTrace();
} finally {
    cs.close();
    rs.close();
}

不是这个

} catch (SQLException sqle) {
    sqle.printStackTrace();
}
rs.close();
cs.close();

【问题讨论】:

  • 请注意,如果您的第一个 close 抛出异常,您将永远无法到达第二个。事实证明,通常最好不要将拙劣的catchfinally 与相同的try 块一起使用。
  • java7 不再需要:AutomaticResourceManagement, try(new resourceDeclartion()){}

标签: java try-catch-finally


【解决方案1】:

根据 HeadFirst Java,即使 try 或 catch 块有 return 语句,finally 块也会运行。流程跳转到 finally,然后返回返回。

【讨论】:

  • 我不同意。这个答案其实很重要。到目前为止,大多数答案都是完全错误的,但 Aditi 给出了一个关键原因,说明您有时可能想要使用“finally”,因此她值得称赞。
【解决方案2】:

如果你捕获了所有错误,应该没有区别,否则只会执行 finally 块中的代码,因为代码执行顺序是: finally 代码 -> 错误抛出 -> 捕获后的代码 因此,一旦您的代码抛出任何未处理的错误,只有 finally 代码块按预期工作。

【讨论】:

    【解决方案3】:

    finally 块可能并不总是运行,请考虑以下代码。

    public class Tester {
        public static void main(String[] args) {
            try {
                System.out.println("The main method has run");
                System.exit(1);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                System.out.println("The finally block has run");
            }
        }
    }
    

    在您的情况下,我建议将 finally 块中的代码包装到 try/catch 中,因为该代码显然可能会引发异常。

        } catch (SQLException sqle) {
            sqle.printStackTrace();
        } finally {
         try {
            cs.close();
            rs.close();
         } catch (Exception e) {
          //handle new exception here
        }
    

    【讨论】:

      【解决方案4】:

      因为如果抛出异常try 块之后没有代码 被执行除非异常被捕获。无论您的 try 块内发生什么,始终执行 finally 块。

      【讨论】:

      • >"除非捕获到异常" - 不是用 catch 捕获到异常吗?
      • 我说的是try/catch/finally的整体架构,不是他的具体例子。
      • 这个答案是正确的,可能会抛出不同类型的异常。
      • pilavdzice 是对的,运行时异常可能是一个很好的例子
      • 这有什么不同?如果没有 catch 块,finally 块才有意义。
      【解决方案5】:

      http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html 中,这是一种误导(并且可能是问题的源头):

      The try block of the writeList method that you've been working with here opens a PrintWriter. The program should close that stream before exiting the writeList method. This poses a somewhat complicated problem because writeList's try block can exit in one of three ways.

      1. The new FileWriter statement fails and throws an IOException.
      2. The list.get(i) statement fails and throws an IndexOutOfBoundsException.
      3. Everything succeeds and the try block exits normally.
      

      第四种方式(抛出IOExceptionIndexOutOfBoundsException 以外的异常)丢失。上一页中描述的代码在诉诸 finally 之前只捕获了 (1) 和 (2)。

      我也是 Java 新手,在找到这篇文章之前也有同样的疑问。一般而言,潜在记忆倾向于将自身更多地附加到示例而不是理论。

      【讨论】:

        【解决方案6】:

        考虑到 catch 可以向调用堆栈中的更高级别函数抛出异常。这将导致在将异常抛出到上层之前调用 final。

        【讨论】:

          【解决方案7】:

          因为它确保 finally 块中的内容被执行。 catch 之后的东西可能不会被执行,例如,catch 块中有另一个异常,这是很有可能的。或者你只是做你所做的,并抛出一个包装原始异常的异常。

          【讨论】:

            【解决方案8】:

            因为如果抛出异常,

            • finally 子句中的代码将在异常向外传播时执行,即使异常中止了其余的方法执行;

            • try/catch 块之后的代码不会被执行,除非异常被 catch 块捕获并且不会重新抛出。

            【讨论】:

            • 第二点+1
            【解决方案9】:
            【解决方案10】:

            finally 关键字保证代码被执行。在您的底部示例中,不执行关闭语句。在上面的例子中,它们被执行(你想要什么!)

            【讨论】:

            • 所以代码在catch(){}之后神奇地停止了执行?我不这么认为。
            【解决方案11】:

            finally 块中的代码将在从 catch 块中重新抛出异常之前被调用。这可以确保您在 finally 块中放置的任何清理代码都会被调用。 finally 块之外的代码将不会运行。

            【讨论】:

              【解决方案12】:

              这是避免资源泄漏的方法

              【讨论】:

                【解决方案13】:

                看看你的 catch 块 - 它会抛出 DAOException。因此,即使在您提供的示例中,您的 catch 块之后的语句也不会执行 。您所展示的(将一个异常包装在另一个中)是一种常见模式 - 但另一种可能性是 catch 块“意外”引发异常,例如因为其中一个调用失败了。

                此外,您可能没有捕获其他异常 - 因为您已声明该方法会抛出它们,或者因为它们是未经检查的异常。你真的想因为IllegalArgumentException 被扔到某个地方而泄露资源吗?

                【讨论】:

                  【解决方案14】:

                  您的第二种方法不会执行“关闭”语句,因为它已经离开了方法。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2012-05-30
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-11-17
                    • 2010-11-12
                    • 2012-06-19
                    • 1970-01-01
                    相关资源
                    最近更新 更多