java受检异常在编译期强制处理,必须二选一:try-catch捕获或throws声明;catch顺序须子类优先;推荐try-with-resources防资源泄漏;自定义异常是否受检取决于是否继承exception而非runtimeexception。

Java中受检异常在编译期强制处理,核心是编译器会静态检查每个可能抛出受检异常的调用点,并要求你明确选择“捕获”或“声明”——二者缺一不可,否则直接编译失败。
必须二选一:try-catch 捕获 或 throws 声明
只要方法调用链中某处可能抛出受检异常(如 FileInputStream 构造、Thread.sleep()、Class.forName()),编译器就要求当前方法做出响应:
- 用
try-catch包裹该调用,并在catch块中处理对应异常类型(如IOException、InterruptedException) - 或在方法签名中添加
throws IOException等声明,把责任向上移交 - 不能两者都不做;也不能只
catch(Exception e)却漏掉具体受检类型(因多态捕获不满足编译校验)
catch 块顺序必须严格:子类优先
当一个 try 块可能抛出多个受检异常时,多个 catch 的排列不是随意的:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 子类异常必须写在父类前面,例如
FileNotFoundException要在IOException之前 - 否则编译报错:“exception XXX has already been caught”
- 这是因为编译器按字面顺序匹配,一旦父类
catch先命中,子类分支就永远无法到达
资源管理别只靠 try-catch:用 try-with-resources 防泄漏
单纯加 try-catch 不代表安全。比如打开文件流后未关闭,即使捕获了异常,仍可能句柄泄漏:
- 推荐使用
try-with-resources(Java 7+),它自动调用close(),无论是否异常都会执行 - 前提是资源类实现
AutoCloseable(FileInputStream、BufferedReader等均已实现) - 写法示例:
try (FileInputStream fis = new FileInputStream("a.txt")) { ... } - 括号内只能是资源声明语句,不能混入其他逻辑,否则编译报错
自定义异常也遵循同一规则
你写的异常类是否受编译器强制,取决于它的继承关系:
- 继承
Exception且不继承RuntimeException→ 是受检异常,调用时必须处理 - 继承
RuntimeException→ 是非受检异常,编译器不管 - 典型业务场景建议:余额不足、权限拒绝等“可预期但需干预”的问题,用受检异常;参数非法、状态错乱等“代码写错了”的问题,用非受检异常
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










