finally 块中的异常
Posted
技术标签:
【中文标题】finally 块中的异常【英文标题】:Exception in finally block 【发布时间】:2018-03-18 03:41:01 【问题描述】:如果 finally 代码块中引发了异常,finally 块的其余部分是否执行?
try
statementList1
finally
command;
command_that_raises;
critical_command;
end
critical_command
会被执行吗?
Manual 只讨论异常,不讨论代码执行:
如果引发了异常但未在 finally 子句中处理,则该异常会从 try...finally 语句中传播出去,并且任何已在 try 子句中引发的异常都会丢失。因此 finally 子句应该处理所有本地引发的异常,以免干扰其他异常的传播。
【问题讨论】:
您引用的手册部分肯定与您的问题有关,因为您要询问 如果在 finally 代码块中引发了 异常...。所以我不知道你为什么认为它不适用。由于执行导致此类异常的代码而发生异常。根据手册,如果command_that_raises
导致异常,那么除非您在finally
块内处理它,否则您将丢失当前异常并且不会执行critical_command
。就像手册说的那样。
好吧,我想,由于 finally 块是保证执行的,所以所有行都被强制逐行执行。我猜我错了。
这就是为什么你通常会在 finally 块中看到,只有不能引发的代码。
难道你不能在大约两分钟内在一个包含大约 10 行代码的快速控制台应用程序中解决这个问题吗?在跑去发布一个需要更长时间编写、格式化和发布的问题之前,实际上试图通过一些实验自己回答问题的人发生了什么?
可能是因为它很容易测试,结果也很容易解释,之前没人愿意讨论它......
【参考方案1】:
查看以下确认:
procedure TForm6.Button1Click(Sender: TObject);
begin
try
ShowMessage('begin');
finally
ShowMessage('enter');
raise Exception.Create('raise');
ShowMessage('end');
end;
end;
现在对于这个案例:
procedure RaiseAndContinue;
begin
try
raise Exception.Create('raise');
except
end;
end;
procedure TForm6.Button1Click(Sender: TObject);
begin
try
ShowMessage('begin');
finally
ShowMessage('enter');
RaiseAndContinue;
ShowMessage('end');
end;
end;
简短的回答是:除非您处理该异常,否则否代码将不会被执行。
【讨论】:
以上是关于finally 块中的异常的主要内容,如果未能解决你的问题,请参考以下文章