我几乎可以肯定答案是肯定的。如果我使用一个尝试最后块,但不使用一个捕获块,然后任何异常将泡沫。对吗?
对这个练习有什么想法吗?
赛斯
是的,绝对会的。当然,假设您的 finally块没有抛出异常,在这种情况下,这将有效地“替换”最初抛出的异常。
finally
是的。小心点.当您的 finally 块正在运行时,它完全有可能正在运行,因为 引发了未处理的、意外的异常。这意味着某些东西是 支离破碎,而 完全出乎意料的事可能正在发生。
在这种情况下,可以说您根本不应该在 finally 块中运行代码。Finally 块中的代码可能被构建为假设它所依赖的子系统是健康的,而实际上它们可能已经被严重破坏了。Finally 块中的代码可能会使情况变得更糟。
例如,我经常看到这样的事情:
DisableAccessToTheResource(); try { DoSomethingToTheResource(); } finally { EnableAccessToTheResource(); }
这段代码的作者在想: “我正在对世界的状态进行一次暂时的突变; 我需要将这个状态恢复到我被称为之前的状态。”。但是让我们想想所有可能出错的地方。
首先,调用方可能已经禁用了对资源的访问; 在这种情况下,这段代码可能过早地重新启用资源。
其次,如果 DoSomething ToTheResource 抛出异常,启用对资源的访问是否正确? ? ?管理资源的代码是 意想不到的破碎。这段代码实际上是说“如果管理代码被破坏,则 确保其他代码可以尽快调用那个破碎的代码,这样它也可以可怕地失败”这似乎不是个好主意。
第三,如果 DoSomething ToTheResource 抛出异常,那么我们如何知道 EnableAccessToTheResource 不会也抛出异常?无论资源的使用情况如何糟糕,都可能影响清理代码,在这种情况下,原始异常将丢失,问题将更难诊断。
我倾向于不使用 try-finally 块编写这样的代码:
bool wasDisabled = IsAccessDisabled(); if (!wasDisabled) DisableAccessToTheResource(); DoSomethingToTheResource(); if (!wasDisabled) EnableAccessToTheResource();
现在国家不会变异,除非有必要。现在调用者的状态不会被扰乱。现在,如果 DoSomething ToTheResource 失败,那么我们不会重新启用访问。我们假设某些东西已经严重损坏,并且不会因为试图继续运行代码而使情况变得更糟。如果可以的话,让打电话的人来处理这个问题。
那么什么时候运行 finally 块是个好主意呢?首先,当出现异常时。例如,您可能认为锁定文件的尝试可能会失败,因为其他人已经锁定了该文件。在这种情况下,捕获异常并将其报告给用户是有意义的。在这种情况下,关于什么被打破的不确定性减少了; 你不太可能通过清理使事情变得更糟。
其次,当您正在清理的资源是稀缺的系统资源时。例如,在 finally 块中关闭文件句柄是有意义的。(“ using”当然只是另一种写 try-finally 块的方式。)文件的内容可能已经被破坏了但你现在无能为力了。文件句柄最终将被关闭,因此最好尽快关闭。