在try / finally中,尝试内部的内容是否重要?

时间:2014-06-03 01:51:47

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

有任何功能差异吗?

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

vs

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

vs

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

我觉得他们所有人都会做同样的事情

2 个答案:

答案 0 :(得分:2)

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块的上下文中。在第二个版本中,没有注册的异常处理程序,并且调用了默认的异常处理程序(意味着未捕获的异常)。

答案 1 :(得分:1)

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

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

您必须认为finally块中的代码总是会执行而不管是什么,并且它将在整个方法完成后执行,因此其他代码是否无关紧要位于try-finally构造的内部或外部,但这不正确。

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

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

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

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