Java受检异常必须显式处理,即用try-catch捕获或用throws声明抛出;所有继承Exception但不继承RuntimeException的异常(如IOException、SQLException)均属此类,代表可预期的外部问题。

Java受检异常(Checked Exception)必须被显式处理,否则编译不通过。这包括两种合法方式:在方法内部用 try-catch 捕获并处理,或在方法签名中用 throws 声明抛出给调用者处理。不能两者都不做,也不能仅靠运行时检查绕过。
哪些异常属于受检异常
所有继承自 java.lang.Exception 但**不继承自 RuntimeException** 的异常都是受检异常。典型例子包括:IOException、SQLException、ClassNotFoundException 等。它们代表程序可能遇到的、可预期且应主动应对的外部问题(如文件不存在、网络中断、数据库连接失败)。
-
Exception是受检异常的父类,但RuntimeException及其子类(如NullPointerException、ArrayIndexOutOfBoundsException)是不受检的,无需强制处理 - 自定义异常若想成为受检异常,需直接继承
Exception;若继承RuntimeException,则为不受检异常
try-catch:在当前方法内消化异常
使用 try-catch 表示你已决定在此处承担处理责任。捕获后应有明确逻辑,而非空 catch 块或仅打印堆栈(除非是临时调试)。
- 一个
try可接多个catch,按异常类型从具体到宽泛排列(例如先FileNotFoundException,再IOException) - 推荐配合
finally或 try-with-resources 自动释放资源(如FileInputStream、Connection),避免资源泄漏 - 若 catch 中无法完全恢复,可转换为更上层能理解的业务异常(如包装成
UserServiceException)再抛出
throws:把责任移交调用方
当方法自身不适合或无法妥善处理异常时,应在方法声明末尾添加 throws XxxException,将异常“声明”出去。调用该方法的代码就必须面对它——要么继续 try-catch,要么也加 throws 向上传递。
立即学习“Java免费学习笔记(深入)”;
- 一个方法可声明抛出多个受检异常,用逗号分隔:
throws IOException, SQLException - 若重写父类方法,子类方法声明的受检异常不能比父类更宽泛(即只能相同或更具体),这是为了保证多态调用的安全性
- 构造器、私有方法、工具方法等若调用可能抛出受检异常的 API,又不想在内部处理,就只能用
throws——哪怕只有一行new FileInputStream(...)
常见误区与注意事项
受检异常的设计初衷是提升健壮性,但滥用会增加代码噪音。关键在于判断“谁最该负责”。
- 不要为吞掉异常而 catch:空 catch 或只写
e.printStackTrace()会让问题静默失效,难以排查 - 不要过度 throws:频繁把异常一路向上推到顶层(如
main方法),等于放弃处理责任,违背设计本意 - 注意接口方法的
throws声明:实现类方法不能抛出比接口声明更宽泛的受检异常 - lambda 表达式中调用可能抛出受检异常的方法?需自行包装(如用自定义函数式接口或 try-catch 包裹)——因为标准函数式接口不支持受检异常


















