异常处理:是在 throw 之后最终执行吗?
Posted
技术标签:
【中文标题】异常处理:是在 throw 之后最终执行吗?【英文标题】:Exception handling: Is finally executed after throw? 【发布时间】:2010-12-07 07:35:58 【问题描述】:假设你有以下代码:
而不是做:
Try
'
' Initialize some objects
'
'
' do something that fails
'
'
' Clean up-code that gets not reached because exception
'
Catch e As Exception
'
'Clean up initialized objects
'
Throw e
End Try
我想做:
Try
'
' Initialize some objects
'
'
' do something that fails
'
Catch e As Exception
Throw e
Finally
'
'Clean up initialized objects
'
End Try
所以我的简单问题是:如果出现异常,即使之前有 throw 一些行,是否也会到达 finally 块?
[编辑] 感谢您的快速答复。
我认为在第一行会有 NullReference-、COM- 和 FileNotFound-Exceptions。
好的,我会去这个代码:
Try
'
' Initialize some objects
'
'
' do something that fails
'
Catch e As Exception ' or just "Catch"??
Throw
Finally
'
'Clean up initialized objects
'
End Try
一切顺利!
创新
【问题讨论】:
你不应该写Throw e
,而应该写Throw
。否则,您将重置异常堆栈跟踪,因此您会丢失有关最初引发异常的位置的信息
【参考方案1】:
所以我的简单问题是:如果出现异常,即使之前有 throw 一些行,是否也会到达 finally 块?
是的。 Finally
block 总是1) 被执行,并且精确地存在以进行清理。在您的代码中,删除 Catch
块,它什么也不做。更糟糕的是,它实际上破坏了堆栈跟踪,因为您没有重新抛出原始异常,而是抛出了一个新异常。
如果您确实需要 Catch
块然后重新引发异常,请使用以下内容:
Catch e As XyzException
' … do some stuff. '
Throw
End Try
1):警告购买者:有一些例外情况,例如***Exception
(多么合适……)需要特别注意并且可能不会触发Finally
块。正确处理它们通常非常困难。
【讨论】:
Konrad - 最后并不总是被执行。例如,当您有 OutOfMemoryException 时,它不会被执行。 @Pete:对,但这些是特定的边缘情况(但我应该提到它们)。 @Pete:你不是说 ***Exception。在 OutOfMemoryException 的情况下运行 finally 的测试非常容易。 @Konrad:我不能说 OOME 是否会阻止 finally 块运行,但我以前没有听说过。然而,很容易构建一个可以运行的案例,所以皮特的观点并不完全正确。另一方面,据我所知,SOE 将关闭运行时,这将始终阻止 finally 块运行。 @Luke:感谢您的更新和链接。我不知道 OOME 可以做到这一点。但是,它与“当您有 OOME 时不会执行”不同,这是我试图澄清的。【参考方案2】:不,不能保证运行。有一些例外情况——例如 StockOverflowException 和 OutOfMemoryException——不能保证 finally 块的执行。
【讨论】:
【参考方案3】:在几乎所有情况下,Finally 都会在 Try/Catch 块中执行(值得注意的异常包括发生 ***Exception 或 OutOfMemoryException 时)。不过我很好奇,为什么你不自己尝试一下。学习事物的一个有价值的方法是亲自尝试一下——毕竟,你最终可能会接受一个错误或误导性的答案,从那时起你就会在这种谎言下工作。
【讨论】:
我试过了,但我的调试器在抛出时停了下来。我阅读了文档并没有找到我的问题的提示。我问这个问题是为了得到直接属于我的问题和间接属于它的答案(比如“终于在特殊情况下没有执行”之类的提示)。【参考方案4】:注意:System.Environment.FastFail 方法是立即杀死当前进程/线程,而不执行 finally 部分。
【讨论】:
【参考方案5】:是的,无论如何,finally 都会被执行。 (只有少数例外 - Response.Redirect 和多线程的一些情况)
【讨论】:
以上是关于异常处理:是在 throw 之后最终执行吗?的主要内容,如果未能解决你的问题,请参考以下文章
Java异常处理中关键字throws,throw,try,catch,finally分别代表啥意义?在try块中可以抛出异常吗?
JAVA语言如何进行异常处理,关键字throws,throw,try,catch,finally分别代表啥意义在try块中抛出异常吗
Java面试题22 JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?