何时选择已检查和未检查的异常

新手上路,请多包涵

在 Java(或任何其他具有检查异常的语言)中,当创建您自己的异常类时,您如何决定它应该被检查还是不被检查?

我的直觉是说,在调用者可能能够以某种有效方式恢复的情况下,将调用已检查的异常,而未经检查的异常更适用于不可恢复的情况,但我会对其他人的想法感兴趣。

原文由 Matt Sheppard 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 301
2 个回答

Checked Exceptions 很棒,只要您了解何时应该使用它们。 Java 核心 API 未能遵循 SQLException(有时是 IOException)的这些规则,这就是它们如此糟糕的原因。

Checked Exceptions 应该用于可以 合理恢复可预测 但不可 预防 的错误。

未经检查的异常 应该用于其他一切。

我会为你分解这个,因为大多数人误解了这意味着什么。

  1. 可预测但不可预防:调用者尽其所能来验证输入参数,但他们无法控制的某些情况导致操作失败。例如,您尝试读取一个文件,但在您检查文件是否存在和读取操作开始之间有人将其删除。通过声明一个已检查的异常,您是在告诉调用者预料到这种失败。
  2. Reasonable to recover from :告诉调用者预测他们无法从中恢复的异常是没有意义的。如果用户试图从一个不存在的文件中读取,调用者可以提示他们输入一个新的文件名。另一方面,如果方法由于编程错误(无效的方法参数或错误的方法实现)而失败,则应用程序无法在执行过程中解决问题。它能做的最好的事情就是记录问题并等待开发人员稍后修复它。

除非您抛出的异常满足上述 所有 条件,否则它应该使用未经检查的异常。

在每个级别重新评估:有时捕获已检查异常的方法不是处理错误的正确位置。在这种情况下,请考虑对您自己的来电者来说什么是合理的。如果异常是可预测的、不可预防的并且可以合理地让他们从中恢复,那么您应该自己抛出一个已检查的异常。如果不是,则应将异常包装在未经检查的异常中。如果您遵循此规则,您会发现自己将已检查的异常转换为未检查的异常,反之亦然,具体取决于您所在的层。

对于已检查和未检查的异常, 请使用正确的抽象级别。例如,具有两个不同实现(数据库和文件系统)的代码存储库应避免通过抛出 SQLExceptionIOException 来暴露特定于实现的细节。相反,它应该将异常包装在跨越所有实现的抽象中(例如 RepositoryException )。

原文由 Gili 发布,翻译遵循 CC BY-SA 4.0 许可协议

来自 Java 学习者

当发生异常时,您必须捕获并处理异常,或者通过声明您的方法抛出该异常来告诉编译器您无法处理它,然后使用您的方法的代码将必须处理该异常(即使它也可以选择声明它在无法处理时抛出异常)。

编译器将检查我们是否完成了两件事之一(捕获或声明)。所以这些被称为检查异常。但是编译器不会检查错误和运行时异常(即使您可以选择捕获或声明,但这不是必需的)。所以,这两个被称为Unchecked exceptions。

错误用于表示发生在应用程序外部的情况,例如系统崩溃。运行时异常通常是由应用程序逻辑中的错误引起的。在这些情况下你什么也做不了。当发生运行时异常时,您必须重新编写程序代码。因此,编译器不会检查这些。这些运行时异常将在开发和测试期间被发现。然后我们必须重构我们的代码以消除这些错误。

原文由 Espo 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题