我可以为finally
构造的try-catch-finally
部分找到的每个文档都是相同的:finally
块中的代码运行是否发生异常,并且对于放清理代码。
我的问题是......为什么?
我的意思是,这是怎么回事:
try {
doSomething();
}
catch( e) {
somethingFailed(e);
}
finally {
cleanupSomething();
}
比这更好:
try {
doSomething();
}
catch( e) {
somethingFailed(e);
}
cleanupSomething();
换句话说,finally
如何才能继续下去?
答案 0 :(得分:4)
最后实际上非常有用。它绝对是一个值得拥有的工具,因为它本质上可以保护必须管理的资源,而无需等待垃圾收集器。还有其他用途,但这是它的主要用途。
我们为什么要使用它呢?为什么不在catch语句之后放置处理(假设所有异常都被捕获)?
这有一个非常好的理由,那就是控制离开try语句的时候。如果发生这种情况,无论出于何种原因,最终会在控制离开之前被击中。因此,例如,如果没有捕获返回,继续,中断,转到或异常 - 如果在try块中发生的任何一个最终将执行,而您的帖子中的代码将不会因为控件已经离开。如果这是一个重要的资源,它就会被泄露。
答案 1 :(得分:0)
可能会抛出一个未指定要捕获的异常。
此外,我觉得这个结构很有用:
try
{
// do something
}
finally
{
// cleanup, in case an exception occurs, this is always called
}
它保证在更高级别处理的异常情况下调用清理代码。
答案 2 :(得分:0)
finally
- 例如,在Pascal中 - 使用因为try
语句的。这是为什么我们使用它:有时,try语句将起作用,但只是部分 - 而且,这尤其是finally
的原因。在错误"运行"之后try
完成后,我们可能会留下对我们没用的部分或不完整的对象(可能会破坏数据;导致内存问题)。
如果代码失败,我们想要摆脱生成的对象并释放内存(减少开销)。
未嵌套的cleanupSomething()
可能会产生意想不到的后果。它也保证finally
或清理将发生,无论较大或正文代码中发生什么(而不是cleanupSomething()
)。
答案 3 :(得分:0)
请考虑以下事项:
您想要加载大量数据,然后进行处理。在计算Process_The_Data()
之后,不再需要加载的数据。
try{
Load_Big_Data();
Method_That_Fails_Always();
Process_The_Data();
}
catch( e)
{
// we may have no means to handle the exception so let it just pass through
}
finally
{
Delete_The_Data();
}
如果您使用finally
,则可以确保数据被删除。
只是在Delete_The_Data()
- 块中调用catch
是不可能的,因为它可能是我们没有失败,但是希望删除数据。
如果您不最后使用,则永远不会调用Delete_The_Data()
- 方法,并且您无法干净利落地释放内存。这很糟糕。
总而言之:如果finally
出现内存泄漏,如果没有彻底删除,你应该使用try
。