为什么使用finally而不是catch后的代码
为什么这样做
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
cs.close();
rs.close();
}
而不是这样做
} catch (SQLException sqle) {
sqle.printStackTrace();
}
rs.close();
cs.close();
Why do this
} catch (SQLException sqle) {
sqle.printStackTrace();
} finally {
cs.close();
rs.close();
}
Instead of this
} catch (SQLException sqle) {
sqle.printStackTrace();
}
rs.close();
cs.close();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
因为如果抛出异常,在执行
try
块后不会再执行任何代码,除非捕获异常。无论try
块内发生什么情况,finally
块始终都会执行。Because if an exception gets thrown no code after the
try
block is executed unless the exception is caught. Afinally
block is always executed no matter what happens inside yourtry
block.查看您的 catch 块 - 它将抛出 DAOException。因此,即使在您给出的示例中,catch 块之后的语句也不会被执行。。您所展示的(将一个异常包装在另一个异常中)是一种常见模式 - 但另一种可能性是 catch 块“意外”引发异常,例如因为它进行的其中一个调用失败。
此外,可能还有其他您没有捕获的异常 - 要么是因为您已声明该方法会抛出它们,要么是因为它们是未经检查的异常。您真的想因为在某处抛出
IllegalArgumentException
而泄漏资源吗?Look at your catch block - it's going to throw
DAOException
. So the statements after your catch block aren't going to be executed even in the sample you've given. What you've shown (wrapping one exception in another) is one common pattern - but another possibility is that the catch block "accidentally" throws an exception, e.g. because one of the calls it makes fails.Additionally, there may be other exceptions you don't catch - either because you've declared that the method throws them, or because they're unchecked exceptions. Do you really want to leak resources because an
IllegalArgumentException
got thrown somewhere?因为如果抛出异常,
finally 子句中的代码将在异常向外传播时执行,即使异常中止了方法执行的其余部分;
除非异常被catch块捕获并且不重新抛出,否则try/catch块之后的代码不会被执行。
Because if an exception is thrown,
Code in the finally clause will execute as the exception propagates outward, even if the exception aborts the rest of the method execution;
Code after the try/catch block will not get executed unless the exception is caught by a catch block and not rethrown.
根据 HeadFirst Java 的说法,即使 try 或 catch 块有 return 语句,finally 块也会运行。流程跳转到finally,然后返回return。
According to HeadFirst Java, a finally block will run even if the try or catch block has a return statement. Flow jumps to finally and then back to return.
因为它确保了finally块中的内容得到执行。 catch 之后的东西可能不会被执行,比如说,catch 块中还有另一个异常,这是很有可能的。或者你只是做你所做的,并抛出一个包装原始异常的异常。
Because it ensures that the stuff in the finally block gets executed. Stuff after catch might not get executed, say, for example, there is another exception in the catch block, which is very possible. Or you just do what you did, and throw an exception wrapping the original exception.
finally 关键字保证代码被执行。在下面的示例中,关闭语句不会被执行。在上面的例子中,它们被执行(如你所愿!)
The finally keyword guarantees that the code is executed. In your bottom example, the close statements are NOT executed. In the top example, they are executed (what you want!)
您的第二种方法不会执行“关闭”语句,因为它已经离开了方法。
Your second approach won't do the 'close' statements because it is already left the method.
这是避免资源泄漏的方法
This is the way to avoid resource leaks
如果捕获所有错误,则应该没有区别,否则,仅执行finally块内的代码,因为代码执行顺序是:
最后代码->错误抛出->捕获后的代码
因此,一旦您的代码抛出任何未处理的错误,只有finally代码块会按预期工作。
If you catch all errors, there should no difference, otherwise, only code inside finally block is executed because the code execution sequence is:
finally code -> error throw -> code after catch
hence, once your code throw any unhandled error, only finally code block works as expected.
在从 catch 块重新抛出异常之前,将调用 finally 块中的代码。这可确保您放入finally 块中的任何清理代码都会被调用。 finally 块之外的代码将不会运行。
The code in the finally block will get called before the exception is rethrown from the catch block. This ensures that any cleanup code that you've put in the finally block gets called. Code outside of the finally block will not be run.
这可能会澄清: http://www.java2s.com/Code/Java /语言-基础/Finallyisalwaysexecuted.htm
this might clarify: http://www.java2s.com/Code/Java/Language-Basics/Finallyisalwaysexecuted.htm
考虑到 catch 可能会向调用堆栈中的更高级别函数抛出异常。这将导致在向上层抛出异常之前调用final。
consider the catch can throw an exception to the higher level functions in the call stack. This will lead calling final before throwing the exception to the upper level.
在 http://docs.oracle.com/javase/tutorial/essential/ exceptions/finally.html 这是误导性的(并且可能引发了问题):
您在此处使用的 writeList 方法的 try 块打开了一个 PrintWriter。程序应在退出 writeList 方法之前关闭该流。这带来了一个有点复杂的问题,因为 writeList 的 try 块可以通过三种方式之一退出。
第四种方式(除了
IOException
和IndexOutOfBoundsException 之外的异常)
被抛出)丢失。上一页中描述的代码在求助于finally
之前仅捕获 (1) 和 (2)。我也是 Java 新手,在找到这篇文章之前也有同样的疑问。一般来说,潜在记忆更倾向于实例而不是理论。
In http://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html this is misleading (and may have originated the question):
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.
The 4th way (an exception other than
IOException
andIndexOutOfBoundsException
is thrown) is missing. The code depicted in the preceding page only catches (1) and (2) before resorting tofinally
.I'm also new to Java and had the same questioning before finding this article. Latent memory tend to attach itself more to examples than to theory, in general.
finally 块可能并不总是运行,请考虑以下代码。
在你的情况下,我建议将finally块内的代码包装到try/catch中,因为该代码显然可能会引发异常。
The finally block may not always run, consider the following code.
In your case, I would suggest to wrap the code inside finally block into try/catch, as this code apparently may throw an exception.