# 捕获或 Specify Requirement

有效的 java 代码必须满足 CatchSpecify Requirement(怎么理解?)。 这意味着某些抛出异常的代码必须包含以下任意一项

  • 一个 try 语句异常声明。必须提供一个处理异常的程序
  • 一个指定它可以抛出异常的方法。该方法必须提供 throws 抛出异常列表的声明。

无法执行 Catch 或 Specify Requirement 的代码将无法编译

并非所有的异常都受 Catch 或 Specify Requirement 的约束。为了理解为什么,我们需要看看三个基本类别的异常。 其中只有一个符合要求。

# 第一种

checked exception。例如,假设应用程序提示用户输入文件名,然后将文件名传递给构造函数来打开该文件(java.io.FileReader)。 但是如果给定的文件不存在的话,那么将会抛出 throws java.io.FileNotFoundException 异常。 因此一个良好的程序应该捕获此异常并通知用户错误,可能会提示修正文件名。

受检异常 仅限于 捕获 或 Specify Requirement。除了 Error、RuntimeException 和他们的子类

# 第二种

error。 这些是应用程序外部的特殊条件,并且应用程序无法预期或恢复。例如,假设应用程序成功打开文件进行输入, 但由于硬件或系统故障而无法读取该文件。不成功的读取将抛出 java.io.IOError。 应用程序可能选择捕获此异常,以便通知用户该问题 ,但是程序也可以打印堆栈跟踪并退出

# 第三种

运行时异常。这些是应用程序内部的特殊情况,应用程序通常无法预期或恢复。 这些通常表示编程错误,例如逻辑错误或 API 的不当使用。例如,考虑前面描述的将文件名传递给构造函数的应用程序 FileReader。 如果一个逻辑错误导致一个 null 传递给构造函数,构造函数将抛出 NullPointerException。 应用程序可以捕获此异常,但它可能更有意义,以消除导致异常发生的错误。

运行时异常不受 捕获或 Specify Requirement 约束。运行时异常是由 RuntimeException 及其子类指示的异常。

错误(error)和运行时异常统称为非检查异常。

# 绕过捕获或 Specify Requirement

一些程序员认为 Catch 或 Specify Requirement 是异常机制的严重缺陷,并通过使用未检查的异常代替检查的异常来绕过它。 一般来说,这是不推荐。Unchecked 异常 - 争议 部分 - 讨论何时使用非检查异常的异常是恰当的。