子类重写父类方法时,抛出的检查型异常不得比父类更宽,只能缩小或保持范围;运行时异常不受限制,可自由抛出;应对新增异常可捕获转换、包装为runtimeexception或谨慎升级父类throws声明。

子类重写父类方法时,抛出的异常类型必须满足编译期契约:不能比父类声明的检查型异常(checked exception)范围更宽。这是Java为保障多态调用安全而设的硬性规则,不是建议,而是编译器直接拦截的错误。
只能缩小或保持异常范围
如果父类方法声明 throws IOException,子类可选择:
- 不抛出任何异常(即省略
throws) - 只抛
IOException的子类,如FileNotFoundException - 抛多个同级或更具体的异常(如
throws FileNotFoundException, EOFException),前提是它们都是IOException的子类
禁止扩大或新增检查型异常
以下写法全部编译失败:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 抛出父类异常的父类,例如
throws Exception或throws Throwable - 新增无关的检查型异常,例如
throws IOException, SQLException - 父类没写
throws,子类却加了throws IOException
运行时异常不受限制
RuntimeException 及其子类(如 IllegalArgumentException、NullPointerException)属于未检查异常。子类重写时可以自由抛出,无需声明在 throws 子句中,也不受父类约束。这是处理“父类未覆盖但子类确实可能出错”的常用方式,比如把 SQLException 包装成 new RuntimeException(e)。
常见应对策略
当子类逻辑需要表达新错误语义,又不能违反规则时,可选:
- 在子类内部
try-catch捕获额外检查异常,转为日志、默认值或重新包装为父类允许的异常再抛 - 将新增异常转为自定义
RuntimeException子类,明确业务含义(如DataAccessException) - 谨慎升级父类
throws声明(如改为throws DataAccessException),但需评估对所有子类和调用方的影响
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










