【问题标题】:In try/finally, does it matter what's inside the try?在 try/finally 中,try 中的内容是否重要?
【发布时间】:2014-06-03 01:51:46
【问题描述】:

有什么功能上的区别吗?

Connection c = null;
try {
  c = getConnection();
  c.doStuff();
} finally {
  if (c!=null) c.close();
}

对比

Connection c = null;
c = getConnection();
c.doStuff();
try {
} finally {
  if (c!=null) c.close();
}

对比

Connection c = null;
try {
  c = getConnection();
} finally {
  if (c!=null) c.close();
}
c.doStuff();

我觉得他们在所有情况下都会做同样的事情

【问题讨论】:

  • 如果您知道try 背后的目的,那么您就知道答案了。如果你不把它放在你的 try 中,你就无法捕捉到异常。
  • 你应该注意异常处理,简单的情况,尝试关闭你的数据库。
  • 这三个示例的行为非常不同。在try 块之外发生的异常就是未处理异常的定义。在这种情况下,您的finally 代码不太可能永远 运行。在最后一个示例中,连接将在您尝试使用它之前关闭。唯一正确的例子是第一个。

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


【解决方案1】:

Craig 已经解决了未处理的异常问题,但我想澄清一下。我编写了两个示例(最后一个示例很糟糕,因为在发生异常后您可能正在处理断开的连接,请不要这样做)。这是一个抛出 ArrayIndexOutOfBoundsException 的简单示例:

class TryCatchFinally {
    static int [] array = new int[1];
    public static void main(String [] args) throws Exception {
        if (args[0].startsWith("1")) {
            version1();
        } else if (args[0].startsWith("2")) {
            version2();
        }
    }
    static int version1() {
        int r = 0;
        try {
            System.out.println("In Try.");
            return array[1];
        } catch (Exception e) {
            System.out.println("In Catch.");
        } finally {
            System.out.println("In Finally.");
        }
        System.out.println("In Return.");
        return r;
    }
    static int version2() {
        int r = array[1];
        try {
            System.out.println("In Try.");
        } catch (Exception e) {
            System.out.println("In Catch.");
        } finally {
            System.out.println("In Finally.");
        }
        System.out.println("In Return.");
        return r;
    }
}

这里是执行:

(TryCatchFinally)$ javac *.java
(TryCatchFinally)$ java TryCatchFinally 1
In Try.
In Catch.
In Finally.
In Return.
(TryCatchFinally)$ java TryCatchFinally 2
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
    at TryCatchFinally.version2(TryCatchFinally.java:24)
    at TryCatchFinally.main(TryCatchFinally.java:7)
(TryCatchFinally)$

正如您在第一个版本中看到的那样,注册了异常处理程序,因为异常发生在 try 块的上下文中。在第二个版本中,没有注册异常处理程序,而是调用了默认的异常处理程序(意味着未捕获的异常)。

【讨论】:

    【解决方案2】:

    try-finally 块之外发生的异常根据定义是未处理的异常。在这种情况下,您无法保证操作系统或运行时将如何处理它。很有可能不会触发异常展开,您的代码将简单地中止(也许 abend 在此讨论中更好地描述了它 - “异常结束”),并且您的 finally 块将永远不会执行。

    try-finally 的重点是保证代码清理发生,并且发生在正确的上下文中。

    你一定认为finally块中的代码无论如何都会执行,并且会在整个方法完成后执行,因此是否找到其他代码无关紧要try-finally 构造内部或外部,但这是不正确的。

    因此,如果您想要任何正确行为的运行时保证,您的第一个示例就是唯一正确的示例。

    • 在您的第一个示例中,您在try 块内获取并且更重要的是使用一个连接(到数据库,可以假定)。如果try 块内发生异常,则finally 块将执行并关闭您的连接。

    • 在您的第二个示例中,您的连接完全在 try-catch 构造之外获取和使用。如果使用连接发生异常,很可能整个上下文将被丢弃,您的finally 块将不会执行,并且您的连接也不会关闭。

    • 在第三个示例中,finally 将在 try 之后执行,但在 finally 块之后的任何代码之前执行。您将在尝试使用该连接时产生异常,因为该连接已被显式关闭。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-17
      • 1970-01-01
      • 2018-03-19
      • 2017-07-20
      • 2013-07-08
      • 2013-05-18
      • 2010-09-29
      相关资源
      最近更新 更多