我了解“ finally”关键字在各种语言中的用途,但是,我很难理解为什么,您会在口味偏爱格式之外使用它。
例如,在PHP中:
v1.2_b7_code
v1.2_b7_docs
v1.2_b7_demo
v1.2_b7_changelog
此代码正在执行的操作与此有何区别?
try {
possibleErrorThrownFunction();
}
catch (CustomException $customException) {
// handle custom error
}
catch (Exception $exception) {
// handle the error
}
finally {
// run this code every single time regardless of error or not
}
由于捕获了错误,最后一行不是总会运行吗?在这种情况下,除非您只想维护代码样式的格式,否则没有真正使用try {
possibleErrorThrownFunction();
}
catch (CustomException $customException) {
// handle custom error
}
catch (Exception $exception) {
// handle the error
}
// run this code every single time regardless of error or not
的情况?
如果我在这里遗漏了一些东西,那么一个示例是一个示例,其中一个finally
语句是必要的,并且不同于仅将代码放在try / catch语句之后。
答案 0 :(得分:30)
Finally
块无论在try
和catch
块内部发生什么情况,都可以运行,然后允许程序崩溃。
这是这里的一种解释:https://www.php.net/manual/en/language.exceptions.php,尽管解释不是特别详细。
一个最重要的例子是,如果要处理输入/输出流或类似的东西,在使用后必须将其关闭以避免内存泄漏。以您的示例为例:
try {
memoryUser.startReading(someFileOrSomething);
}
catch (CustomException $customException) {
// handle custom error
}
catch (Exception $exception) {
// handle the error
invisibleBug.whoops(); // i.e. something goes wrong in this block
}
memoryUser.Close(); // because something went wrong in the catch block,
// this never runs, which, in this case, causes a memory leak
在这种情况下,将memoryUser.Close();
包装在finally
块中将确保该行将在程序其余部分爆炸之前运行,即使在发生灾难性故障时也可以防止内存泄漏。
很多时候,即使人们忽略了捕获块中的某些内容,人们也将final块放置在此处以确保重要的一行运行。这就是我一直看到它使用的方式。
希望这会有所帮助:)
答案 1 :(得分:26)
finally {}
块的特殊之处在于,它将{strong>始终运行在try {}
块的末尾。
如果try {}
块中的代码成功完成,它将运行。
如果try {}
块中的代码引发catch {}
捕获的异常,它将运行。 (finally {}
在catch {}
之后运行。)
如果try {}
块中的代码引发了一个catch {}
块未处理的异常,或者根本没有任何异常,它将运行。 (finally {}
块在异常传播到调用者之前运行。)
如果try {}
块中的代码引发异常,并且catch {}
中的代码引发另一个异常(或重新引发相同的异常),它将运行)。
如果try {}
块或catch {}
块中的代码使用return
,它将甚至运行。 (就像未捕获的异常一样,finally {}
在函数实际返回之前运行。)finally {}
块甚至可以使用return
本身,并且其返回值将覆盖另一个值块试图返回!
(在一种极端情况下,finally {}
块不会运行,那就是整个过程都被破坏了,例如被杀死,或通过调用exit()
或die()
)