何时选择选中和未选中的例外

2022-08-31 05:31:39

在 Java(或任何其他具有已检查异常的语言)中,在创建自己的异常类时,如何决定是应选中还是取消选中?

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


答案 1

选中的异常很棒,只要您了解何时应使用它们即可。Java核心API未能遵循SQLException的这些规则(有时也适用于IOException),这就是为什么它们如此糟糕。

选中的异常应用于可预测不可预防的错误,这些错误可以合理地从中恢复

未选中的例外应用于其他所有内容。

我会为你分解这一点,因为大多数人都误解了这是什么意思。

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

除非您引发的异常满足上述所有条件,否则它应使用“未选中的异常”。

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

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


答案 2

来自 Java 学习者

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

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

错误用于表示在应用程序外部发生的那些情况,例如系统崩溃。运行时异常通常是由于应用程序逻辑中的错误而发生的。在这些情况下,您无法执行任何操作。当运行时发生异常时,您必须重写程序代码。因此,编译器不会检查这些。这些运行时异常将在开发和测试期间发现。然后,我们必须重构代码以删除这些错误。