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

Jak*_*ake 16 php error-handling try-catch

我了解“ finally”关键字在各种语言中的含义,但是,我很难理解为什么您会在口味偏爱格式之外使用它。

例如,在PHP中:

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
}
Run Code Online (Sandbox Code Playgroud)

这段代码在做什么和这样做之间有什么区别?

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
Run Code Online (Sandbox Code Playgroud)

由于捕获了错误,最后一行不是总会运行吗?在这种情况下,finally除非您只想维护代码样式的格式,否则没有实际使用的情况?

finally如果我在这里遗漏了一些东西,那么一个例子是必要的,并且不同于仅将代码放在try / catch语句之后的例子。

Rea*_*ins 30

简短答案

Finally无论在try和程序catch块内发生什么,都保证程序块可以运行,然后再使程序崩溃。

此处对此进行了某种解释:https : //www.php.net/manual/zh/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
Run Code Online (Sandbox Code Playgroud)

在这种情况下,将memoryUser.Close();in 包裹在一个finally块中将确保该行在程序的其余部分爆炸之前运行,即使在发生灾难性故障时也可以防止内存泄漏。

TL; DR

因此,很多时候,即使他们忽略了捕获块中的某些内容,人们也将finally块放置在此处以确保重要的一行运行。这就是我一直看到它使用的方式。

希望这会有所帮助:)

  • 精确地:)当捕获可能非常简单时(例如`System.out.println(“ uh oh”);`),当您可能不需要finally块时,另一个可能的例外是它,但是我通常只喜欢安全而不后悔:) @adam谢谢你,也很好。我对Java较为熟悉,但是认为概念是相同的。 (2认同)

dus*_*uff 26

finally {}块的特殊之处在于它将始终try {}块的末尾运行。

  • 如果try {}块中的代码成功完成,它将运行。

  • 如果代码try {}块中的代码引发由捕获的异常,它将运行catch {}。(。finally {}之后的运行catch {}。)

  • 如果该try {}块中的代码引发了一个未被任何catch {}块处理的异常,或者根本没有任何异常,它将运行。(该finally {}块在异常传播到调用者之前运行。)

  • 如果try {}块中的代码引发异常,并且该代码catch {}引发另一个异常(或重新引发相同的异常),它将运行。

  • 它甚至会运行,如果在代码try {}块,或者在catch {}块的用途return。(就像未捕获的异常一样,在finally {}函数实际返回之前运行。)该finally {}块甚至可以使用return其自身,并且其返回值将覆盖另一个块试图返回的值!

(在一种极端情况下,一个finally {}块将不会运行,也就是说,整个过程都被破坏了,例如,被杀死或调用exit()die()。)