Java教程适用于JDK 8。本页面中描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
请参阅Java语言更改了解Java SE 9及其后续版本中更新的语言功能的概述。
请参阅JDK发行说明了解所有JDK版本的新功能、增强功能以及已删除或已弃用选项的信息。
由于Java编程语言不要求方法捕获或指定未经检查的异常(RuntimeException
,Error
及其子类),程序员可能会倾向于编写只抛出未经检查的异常或使所有异常子类继承自RuntimeException
的代码。这两种捷径使程序员能够编写代码,而不必理会编译器错误,也不必指定或捕获任何异常。尽管对程序员来说这可能很方便,但它规避了catch
或specify
要求的意图,并可能给使用您的类的其他人带来问题。
为什么设计者决定强制方法指定在其范围内可能抛出的所有未捕获的已检查异常?可以通过方法抛出的任何Exception
都是方法的公共编程接口的一部分。调用方法的人必须了解方法可能抛出的异常,以便决定如何处理它们。这些异常与该方法的参数和return
值一样,都是该方法的编程接口的一部分。
下一个问题可能是:“如果记录方法的API很好,包括它可以抛出的异常,为什么不指定运行时异常呢?”运行时异常表示由编程问题导致的问题,因此,API客户端代码不能合理地预期从中恢复或以任何方式处理它们。这些问题包括算术异常,如除以零;指针异常,如试图通过空引用访问对象;和索引异常,如尝试通过过大或过小的索引访问数组元素。
运行时异常可以在程序的任何地方发生,在典型的程序中可能会非常多。必须在每个方法声明中添加运行时异常会降低程序的清晰度。因此,编译器不要求您捕获或指定运行时异常(尽管您可以)。
通常情况下,常见做法之一是在用户错误调用方法时抛出RuntimeException
。例如,方法可以检查其参数之一是否错误地为null
。如果参数为null
,则方法可能会抛出NullPointerException
,这是一个未经检查的异常。
一般而言,不要因为不想麻烦地指定方法可能抛出的异常,而抛出RuntimeException
或创建RuntimeException
的子类。
下面是底线准则:如果客户端可以合理地预期从异常中恢复,将其作为已检查的异常。如果客户端无法采取任何措施从异常中恢复,将其作为未经检查的异常。