为什么在catch之后使用finally而不是代码

时间:2011-01-14 14:17:29

标签: java try-catch-finally

为什么这样做

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

而不是这个

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

14 个答案:

答案 0 :(得分:73)

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

答案 1 :(得分:24)

看看你的阻挡区 - 它将抛出DAOException。所以即使在你给出的样本中,你的catch块之后的语句也不会被执行。你所展示的内容(将一个例外包装在另一个例外中)是一种常见的模式 - 但另一种可能性是,catch块“意外地”抛出异常,例如因为其中一个调用失败了。

此外,您可能还有捕获的其他异常 - 要么是因为您已声明该方法会抛出它们,要么是因为它们是未经检查的异常。你真的想泄漏资源,因为某个地方被IllegalArgumentException抛出了吗?

答案 2 :(得分:11)

因为如果抛出异常,

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

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

答案 3 :(得分:7)

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

答案 4 :(得分:6)

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

答案 5 :(得分:3)

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

答案 6 :(得分:1)

你的第二种方法不会做'关闭'语句,因为它已经离开了方法。

答案 7 :(得分:1)

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

答案 8 :(得分:0)

这是避免资源泄漏的方法

答案 9 :(得分:0)

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

答案 10 :(得分:0)

答案 11 :(得分:0)

考虑catch可以向调用堆栈中的更高级函数抛出异常。这将导致调用final,然后将异常抛到上一级。

答案 12 :(得分:0)

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.

缺少第4路(抛出IOExceptionIndexOutOfBoundsException以外的例外)。在使用finally之前,上一页中描述的代码仅捕获(1)和(2)。

我也是Java的新手,在找到这篇文章之前也有同样的疑问。一般而言,潜在记忆往往更多地依附于实例而不是理论。

答案 13 :(得分:0)

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
    }