继承exception(非runtimeexception子类)为受检异常,编译强制处理;继承runtimeexception为运行时异常,编译不检查。判断依据唯继承关系,与名称、包、用途无关。

关键看继承谁:继承 Exception(且不是 RuntimeException 的子类)就是受检异常;继承 RuntimeException 就是运行时异常。编译器只认这个继承关系,不看名字、不看包路径、也不看用途。
继承 Exception → 受检异常
这类异常编译时强制处理——要么 try-catch,要么在方法签名加 throws。适合表达程序本可预期、外部环境导致的可恢复问题,比如“用户上传的文件格式不支持”“配置项缺失需提示重填”。
- 必须显式声明或捕获,否则编译报错:“unreported exception XXX; must be caught or declared”
- 自定义写法示例:class UnsupportedFileTypeException extends Exception { ... }
- 别为了省事把它包装成 RuntimeException——这会掩盖“需要调用方配合处理”的设计意图
继承 RuntimeException → 运行时异常
编译器完全不管,代码能过编译,运行中才可能抛出。适合表达代码逻辑缺陷,比如“传了 null 却没校验”“状态非法却跳过了守门检查”。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 不强制捕获,但若真要 catch,得有明确目的(如顶层统一日志+告警),而不是静默吞掉
- 自定义写法示例:class InvalidStateException extends RuntimeException { ... }
- 不要在方法签名里写 throws InvalidStateException——编译器不认,也违背语义
验证方式最可靠:看编译器脸色
不用查文档、不用背例子,现场写一行代码就能确认:
- 写 throw new MyException();,不加 try-catch 也不加 throws → 编译失败 → 是受检异常
- 写 throw new MyRuntimeException();,同样不处理 → 编译通过 → 是运行时异常
- IDE 里按 Ctrl/Cmd 点进异常类源码,顺着 extends 往上看到底落到 Exception 还是 RuntimeException 分支
设计时想清楚“谁该负责”
不是技术问题,而是接口契约问题:
- 如果希望调用方必须感知并做应对(比如重试、降级、提示用户),就让它继承 Exception
- 如果只是告诉调用方“你用错了”,或者属于开发阶段该被单元测试揪出的问题,就继承 RuntimeException
- 避免把 IOException 子类改成 RuntimeException 子类来绕过编译检查——这不是简化,是破坏错误传播链
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










