子类重写父类方法时,仅检查异常受throws限制:只能缩小或删除,不可扩大或新增;运行时异常不受限。编译错误提示指向检查异常不兼容,需逐层验证继承链。

子类重写父类方法时,对 throws 声明的控制核心只针对**检查异常(checked exception)**,运行时异常(如 RuntimeException 及其子类)完全不受限制。
只允许缩小或删除检查异常,不能扩大
父类方法声明 throws IOException,子类重写时只能:
- 保持原样:throws IOException
- 缩小范围:throws FileNotFoundException(IOException 的子类)
- 彻底不抛:不写 throws 子句(即内部用 try-catch 处理掉所有检查异常)
- 额外抛出运行时异常:throws IOException, IllegalArgumentException(合法,后者编译器不管)
但以下写法会直接编译失败:
- throws Exception(Exception 是 IOException 的父类,范围更大)
- throws SQLException(与 IOException 无继承关系,属于不同异常体系)
- 父类没写 throws,子类却写 throws IOException(新增检查异常,调用方毫无准备)
关键看编译错误提示,不是看方法体里“抛了什么”
编译器报错通常类似:
error: unreported exception XXXException; must be caught or declared to be thrown
这些提示说明:子类方法体中出现了新检查异常,但 throws 子句没按父类契约声明——要么删掉这个异常(用 try-catch 拦住),要么确保它属于父类 throws 类型的子类。
逐层检查父类 throws 的完整继承链
不能只看父类代码表面写了什么,要确认异常类型是否真能兼容:
- 父类 throws SQLException → 子类可 throws SQLTimeoutException(它是 SQLException 子类)
- 父类 throws SQLException → 子类不可 throws IOException(两者平行,无继承关系)
- 父类 throws Exception → 子类可 throws IOException 或 SQLException(都是 Exception 子类)
如果父类是接口或抽象类,还要向上追溯它的父接口/父类声明,确保整个继承链上的 throws 兼容。
运行时异常可自由增删,别被它干扰判断
IllegalArgumentException、NullPointerException、RuntimeException 等,子类想加就加、想删就删,编译器不检查。如果报错里提到的是这类异常,说明真正的问题不在这里——得回头再找检查异常的越界点。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











