【发布时间】:2009-02-24 15:03:28
【问题描述】:
在 try/catch/finally 块中,例如:
try
{
}
catch()
{
// code fails here
}
finally
{
}
那么如果catch块中有异常,最终总会被调用吗?
如果没有finally,catch块后面的代码会运行吗?
【问题讨论】:
在 try/catch/finally 块中,例如:
try
{
}
catch()
{
// code fails here
}
finally
{
}
那么如果catch块中有异常,最终总会被调用吗?
如果没有finally,catch块后面的代码会运行吗?
【问题讨论】:
假设进程不会突然终止(当然也不会挂起),finally 块将始终被执行。
如果没有 finally 块,来自 catch 块的异常将被抛出堆栈。请注意,最初导致 catch 块被执行的原始异常将被有效地丢失。
堆栈溢出异常
正如 Jared 所指出的,堆栈溢出将导致 finally 块不被执行。我相信这会突然终止程序,但我可能是错的。这是示例代码:
using System;
public class Test
{
static void Main()
{
// Give the stack something to munch on
int x = 10;
try
{
Main();
Console.WriteLine(x);
}
finally
{
Console.WriteLine("Finally");
}
}
}
结果:
由于 StackOverflowException 而终止进程。
【讨论】:
finally 块总是会被执行。如果你排除了 finally 块,并且在 catch 块中发生了异常,那么在 catch 块之后不会执行任何代码,因为本质上你的 catch 块会失败并自己生成一个未处理的异常。
【讨论】:
是的,finally 会一直运行
没有catch块后面的代码不会运行。
即使使用 finally 块,finally 块之后的任何代码都不会运行。
【讨论】:
如果catch块中有异常,finally会执行,但是会抛出一个新的异常。发生异常的catch块不会捕获异常,它会继续向上堆栈。
经验教训:如果你能帮助它,不要在 catch 块中做可以抛出的东西;如果必须,嵌套一个 try/catch 块。
try
{
}
catch()
{
try
{
// code fails here
}
catch
{
// handle that. Or not.
}
}
finally
{
}
【讨论】:
finally 块总是会被执行。来自MSDN:
finally 块可用于清理在 try 块中分配的任何资源,以及运行任何必须执行的代码,即使出现异常也是如此。不管 try 块如何退出,控制总是传递给 finally 块。
catch 用于处理语句块中发生的异常,而 finally 用于保证语句块的执行,而不管前面的 try 块如何退出。
顺便说一句,这种类型的问题您可以通过编写一些代码、编译它并查看执行它时发生的情况来轻松测试自己。
class Program {
static void Main(string[] args) {
try {
Console.WriteLine("Trying!");
throw new Exception();
}
catch (Exception e) {
Console.WriteLine("Catching {0}!", e.Message);
throw new Exception();
}
finally {
Console.WriteLine("Finally!");
}
}
}
这个输出:
Trying!Catching Exception of type 'System.Exception' was thrown.!
Unhandled Exception: System.Exception: Exception of type 'System.Exception' wasthrown.at TestFinally.Program.Main(String[] args) in C:\Documents and Settings\Me\MyDocuments\Visual Studio 2008\Projects\TestFinally\TestFinally\Program.cs:line 15Finally!Press any key to continue . . .
【讨论】:
如果 catch 块中发生异常,finally 中的所有代码仍然会被执行。 如果堆栈中有更高的异常处理程序(例如此函数的调用者),它将捕获此异常。否则会导致未处理的异常并关闭您的应用程序。
catch 块中异常点之后的代码不会被调用。
【讨论】:
只是想添加我知道的不允许 finally 和任何其他代码块执行的情况:
【讨论】: