为什么要使用“最终”关键字?

时间:2019-07-29 20:13:33

标签: php error-handling try-catch

我了解“ 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语句之后。

2 个答案:

答案 0 :(得分:30)

简短回答

Finally块无论在trycatch块内部发生什么情况,都可以运行,然后允许程序崩溃。

这是这里的一种解释: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块中将确保该行将在程序其余部分爆炸之前运行,即使在发生灾难性故障时也可以防止内存泄漏。

TL; DR

很多时候,即使人们忽略了捕获块中的某些内容,人们也将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()