子类重写父类方法时可抛出父类声明受检异常的子类(如ioexception→filenotfoundexception),因语义更明确且不破坏多态契约;但不可抛出平级、父级或无关异常,运行时异常无限制;构造器需显式处理父类构造器的受检异常。

子类重写父类方法时,若父类用 throws 声明了某个受检异常(如 IOException),子类可以安全地改为抛出它的**具体子类异常**(如 FileNotFoundException),这是完全合法且推荐的做法。
为什么允许抛出子类异常?
因为子类异常类型更具体,语义更明确,不会破坏多态调用的契约。调用方按父类声明捕获 IOException,自然也能捕获其子类;而子类缩小异常范围,反而提升了可维护性和错误定位能力。
配置要点(必须满足)
-
只能是父类异常的子类或相同类型:比如父类声明
throws SQLException,子类可写throws SQLTimeoutException(它是SQLException的子类),但不能写throws Exception或throws Throwable -
不能抛出平级或父级异常:父类抛
IOException,子类不能抛Exception(父类)、SQLException(平级,与IOException无继承关系) -
运行时异常不受限制:子类可自由抛出任意
RuntimeException子类(如IllegalArgumentException),无论父类是否声明,也无需出现在throws中
典型代码示例
父类方法:
class DataReader {
void load() throws IOException {
// 可能抛出各种 IO 异常
}
}
子类重写(合法):
class CsvReader extends DataReader {
@Override
void load() throws FileNotFoundException { // ✅ 合法:FileNotFoundException 是 IOException 子类
new FileInputStream("data.csv");
}
}
子类重写(非法):
class BadReader extends DataReader {
@Override
void load() throws Exception { // ❌ 编译错误:Exception 范围比 IOException 更宽
...
}
}
构造器中的特殊处理
子类构造器不继承父类构造器,但若父类构造器声明了受检异常,子类构造器必须显式处理:
- 在自己的
throws中声明相同或更具体的异常 - 或用
try-catch捕获后转为运行时异常包装抛出
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











