检查异常
导航 异常 主题: ) |
检查异常是一种必须在抛出它的方法中捕获或声明的异常类型。例如,java.io.IOException
是一个检查异常。要了解什么是检查异常,请考虑以下代码
代码部分 6.9:未处理的异常。
public void ioOperation(boolean isResourceAvailable) {
if (!isResourceAvailable) {
throw new IOException();
}
}
|
此代码无法编译,因为它可能会抛出检查异常。编译错误可以通过两种方法解决:通过捕获异常并处理它,或者通过使用throws
关键字声明可以抛出异常。
|
|
在 Java 类层次结构中,如果异常继承自java.lang.Throwable
,但不继承自java.lang.RuntimeException
或java.lang.Error
,那么它就是一个检查异常。所有应用程序或业务逻辑异常都应该是检查异常。
一个方法可能声明它可以抛出异常,但实际上它并没有。尽管如此,调用者仍然必须处理它。检查异常声明具有多米诺骨牌效应。任何将使用先前方法的方法也将不得不处理检查异常,依此类推。
因此,Java 编程语言的编译器在编译时通过分析每个方法体来检查程序是否包含所有应用程序异常的处理程序。如果通过执行方法体,可以将异常抛出给调用者,则必须声明该异常。编译器如何知道方法体是否可以抛出异常?这很简单。在方法体内部,对其他方法有调用;编译器查看每个方法签名,它们声明要抛出的异常。
为什么要强制异常处理?
[edit | edit source]这可能看起来对开发人员很无聊,但它迫使他们考虑所有检查异常并提高代码质量。这种在编译时检查异常处理程序的存在是为了让应用程序开发人员的生活更轻松。调试某个抛出的异常是否有一个匹配的捕获将是一个漫长的过程。在像 C 和 C++ 这样的传统语言中,需要单独的错误处理调试。在 Java 中,我们可以确定,当抛出应用程序异常时,该异常在程序中的某个地方会被处理。在 C 和 C++ 中,这必须经过测试。在 Java 中,不需要测试,因此节省下来的时间可以用于更重要的测试,例如测试业务功能。
重写方法时可以声明哪些异常?
[edit | edit source]在throws
关键字后指定的检查异常类是实现者和用户之间的契约的一部分。重写方法可以声明相同的异常、子类或无异常。
实现接口时可以声明哪些异常?
[edit | edit source]JAVA 1.8 及更高版本:当涉及接口时,实现声明可以跳过 throws 子句,但如果希望使用它,则应与接口声明兼容。换句话说,实现应该抛出已声明的异常或它的子类型,或者没有异常。
Java 1.8 之前:实现者必须声明相同的异常或它的子类。