-3

有什么功能上的区别吗?

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();

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

4

2 回答 2

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

于 2014-06-03T02:24:08.167 回答
1

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

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

您一定认为finally块中的代码无论如何都会执行,并且它将在整个方法完成后执行,因此其他代码位于try-finally构造内部还是外部都没有关系,但这是不正确的。

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

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

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

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

于 2014-06-03T02:07:38.217 回答