Jar*_*red 45 c# c++ java exception try-catch-finally
我在解决一些看起来像这样的代码时遇到了非常痛苦的故障排除经验:
try {
doSomeStuff()
doMore()
} finally {
doSomeOtherStuff()
}
Run Code Online (Sandbox Code Playgroud)
这个问题很难解决,因为doSomeStuff()引发了异常,这又导致doSomeOtherStuff()也抛出异常.第二个异常(由finally块抛出)被抛到我的代码中,但它没有第一个异常的句柄(从doSomeStuff()抛出),这是问题的真正根本原因.
如果代码说了这个,那么问题就很明显了:
try {
doSomeStuff()
doMore()
} catch (Exception e) {
log.error(e);
} finally {
doSomeOtherStuff()
}
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是:
是没有任何catch块使用的finally块是一个众所周知的java反模式?(这显然是一个不太明显的子类,显然是众所周知的反模式"不要狼吞虎咽的例外!")
dsi*_*cha 63
一般来说,不,这不是反模式.finally块的重点是确保无论是否抛出异常,都会清理内容.异常处理的重点在于,如果你不能处理它,你可以通过相对干净的带外信令异常处理提供给它的人.如果你需要确保在抛出异常时清理了东西,但是无法在当前范围内正确处理异常,那么这是正确的做法.你可能想要更加小心确保你的finally块不会抛出.
Bry*_*yle 10
尝试最终没有任何问题绝对没有错.考虑以下:
InputStream in = null;
try {
in = new FileInputStream("file.txt");
// Do something that causes an IOException to be thrown
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// Nothing we can do.
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果抛出异常并且此代码不知道如何处理它,那么异常应该将调用堆栈冒泡到调用者.在这种情况下,我们仍然想要清理流,所以我认为有一个没有捕获的try块是完全合理的.
我认为它远非反模式,而且在解决方法执行过程中获取资源的关键时,我经常这样做.
在处理文件句柄(用于写入)时,我做的一件事是在使用IOUtils.closeQuietly方法关闭流之前刷新流,该方法不会抛出异常:
OutputStream os = null;
OutputStreamWriter wos = null;
try {
os = new FileOutputStream(...);
wos = new OutputStreamWriter(os);
// Lots of code
wos.flush();
os.flush();
finally {
IOUtils.closeQuietly(wos);
IOUtils.closeQuietly(os);
}
我喜欢这样做,原因如下:
| 归档时间: |
|
| 查看次数: |
19618 次 |
| 最近记录: |