为什么要使用"finally"关键字?

6 浏览
0 Comments

为什么要使用"finally"关键字?

我理解在各种编程语言中使用\"finally\"关键字的含义,然而,我很难理解为什么除了代码风格的偏好之外还会使用它。\n例如,在PHP中:\n

try {
  possibleErrorThrownFunction();
}
catch (CustomException $customException) {
  // 处理自定义错误
}
catch (Exception $exception) {
  // 处理错误
}
finally {
  // 无论有无错误,每次都执行此代码
}

\n这段代码和这段代码有什么区别?\n

try {
  possibleErrorThrownFunction();
}
catch (CustomException $customException) {
  // 处理自定义错误
}
catch (Exception $exception) {
  // 处理错误
}
// 无论有无错误,每次都执行此代码

\n由于错误被捕捉,最后一行不是总会被执行吗?在这种情况下,除非你只是想保持代码风格的一致性,否则没有真正使用\"finally\"的情况吧?\n如果我在这里有所遗漏,那么一个需要使用\"finally\"语句并且与在try/catch语句后添加代码不同的示例将会很有帮助。

0
0 Comments

为什么使用"finally"关键字?

在编程中,使用"finally"关键字有一些特殊之处,它总是会在"try"块的末尾运行。

它会在"try"块中的代码成功完成时运行。

它会在"try"块中的代码抛出一个被"catch"捕获的异常时运行("finally"在"catch"之后运行)。

它会在"try"块中的代码抛出一个未被任何"catch"块处理的异常时运行,或者根本没有"catch"块。("finally"块在异常传播给调用者之前运行)。

它会在"try"块中的代码抛出异常,并且"catch"中的代码抛出另一个异常(或重新抛出相同的异常)时运行。

甚至在"try"块或"catch"块中使用"return"时,它也会运行。(与未捕获的异常一样,"finally"在函数实际返回之前运行。)"finally"块甚至可以使用"return",它的返回值将覆盖其他块尝试返回的值!

(有一种情况下"finally"块不会运行,那就是如果整个进程被销毁,例如被杀死,或者调用了"exit()"或"die()"。)

为了比较和对比问题中的两个代码片段,在"try/catch/finally"之后的常规代码在哪些情况下会运行也许是值得提及的。(前两种情况?我不确定。)

是的,只有在前两种情况下会运行。

0
0 Comments

为什么使用"finally"关键字?

"finally"块保证在try和catch块内发生任何情况之前运行,并在程序崩溃之前运行。

在处理输入/输出流或类似需要在使用后关闭以避免内存泄漏的情况下,finally块非常有用。例如:

try {

memoryUser.startReading(someFileOrSomething);

}

catch (CustomException $customException) {

// 处理自定义错误

}

catch (Exception $exception) {

// 处理错误

invisibleBug.whoops(); // 在此块中出现错误

}

memoryUser.Close(); // 由于catch块中出现错误,此行永远不会运行,导致内存泄漏

在这种情况下,将memoryUser.Close()包装在finally块中将确保该行在程序崩溃之前运行,即使发生灾难性故障也可以防止内存泄漏。

通常情况下,人们将finally块放在那里,以确保重要的代码行得以运行,即使他们在catch块中忽略了某些内容。这是我一直以来看到的使用方式。

希望对你有所帮助 🙂

总之,当catch语句中发生错误时,finally语句仍然可以运行吗?这意味着实际上你应该使用finally语句,因为你无法总是预测catch语句中的错误?

确实如此 🙂 另一个可能不需要finally块的例外情况是如果catch非常简单(比如可能是System.out.println("uh oh")),但我通常更喜欢安全而不是抱歉 🙂 谢谢你的观察。我更熟悉Java,但我认为这个概念应该是相同的。

"finally块保证在try和catch块内发生任何情况之前运行"。如果PHP与其他语言一样(虽然这是一个大的假设,但它通常不比其他语言更好),我非常怀疑这一点。除了无尽循环的小问题外,PHP确实有一个exit函数,我认为调用的是C运行时的exit,这意味着进程被简单地终止,不会执行finally块。在.NET或Java中也是如此。

有时您也不编写catch块。例如try { ... } finally {... }。然后异常将向上传播(在某个其他方法中捕获并处理),但finally块仍将运行,清理任何需要清理的内容。

有时,您不完全处理异常。比如,在catch中做一些处理(可能是记录或向异常对象添加一些详细信息),然后重新抛出异常,以便某个更高级别的方法可以捕获并正确处理它。同样,finally块将进行清理。

0