有效的Java编程语言代码必须符合Catch或指定要求。这意味着可能引发某些异常的代码必须由以下任一方包括:
- 一个捕获异常的try语句。try语句中必须为异常提供一个处理程序
- 一种指定它可以抛出异常的方法。该方法必须提供一个列出异常的throws子句
不能遵守Catch或指定要求的代码将无法编译。
并不是所有的异常都受到“捕捉”或“指定要求”的限制。为了理解为什么,我们需要看看三个基本类别的例外情况,其中只有一个是符合要求的。
三类异常
checked exception:
这些是应用程序内部的特殊条件,一个健壮的应用程序应该给出预期和错误和异常恢复。
例如,假设应用程序提示用户输入文件名,然后通过将名称传递给java.io.FileReader的构造函数来打开该文件。通常,用户提供现有可读文件的名称,因此FileReader对象的构造成功,并且应用程序的执行正常进行。
但有时用户提供不存在的文件的名称,构造函数会抛出java.io.FileNotFoundException异常。一个写得好的程序会捕获这个异常并通知用户错误,可能会提示修正后的文件名。
检查的异常,受Catch或指定要求的限制。所有异常都是检查异常,除了由Error,RuntimeException及其子类指示的异常。
error:
这些是应用程序外部的特殊条件,并且应用程序通常无法预期或恢复。例如,假设应用程序成功打开文件进行输入,但由于硬件或系统故障,无法读取该文件。不成功的读取将抛出java.io.IOError。一个应用程序可能会选择捕获这个异常,以便通知用户问题 - 但打印堆栈跟踪并退出也是一件非常有意义的事情
error,不受Catch或指定要求的约束。错误是由Error及其子类指出的异常。
运行时异常:(runtime exception)
这些是应用程序内部的特殊条件,并且应用程序通常无法预期或恢复。这些通常表示编程错误,例如逻辑错误或API的不当使用。
例如,考虑将文件名传递给FileReader的构造函数的前面所述的应用程序。如果逻辑错误导致将null传递给构造函数,构造函数将抛出NullPointerException。该应用程序可以捕获此异常,但是消除引起异常发生的错误可能更有意义。
运行时异常不受Catch或指定要求的约束。运行时异常是由RuntimeException及其子类指示的。
错误和运行时异常被统称为未经检查的异常。
避开捕捉、指定情况
一些程序员认为捕获或指定需求在异常机制中存在严重缺陷,并通过使用未经检查的异常代替检查的异常来绕过它。一般来说,这是不推荐的。 “未经检查的例外”部分 -讨论何时使用未经检查的异常。