判断异常类型应依据继承关系:继承自runtimeexception及其子类为运行时异常,继承自exception但非runtimeexception后代的为受检异常;编译器报错“unreported exception”即受检异常,编译通过但运行崩溃多为运行时异常。

关键不在“怎么抛”,而在于“谁该负责”——受检异常要求调用方显式应对,运行时异常则暴露代码自身缺陷,应优先修复而非捕获。
看继承关系,这是最准的判断依据
不用猜名字,直接查类的父类:
- 如果异常类是 RuntimeException 或其任意子类(如 NullPointerException、IllegalArgumentException、ArrayIndexOutOfBoundsException),就是运行时异常
- 如果异常类继承自 Exception 但不是 RuntimeException 的后代(如 IOException、SQLException、ClassNotFoundException),就是受检异常
- IDE 中按住 Ctrl(Windows)或 Cmd(macOS)点击异常类名,一眼就能看到 extends 谁
靠编译器反馈,现场验证最快
写一行可能出问题的代码,不加 try-catch 也不加 throws,然后编译:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 编译失败,报错 “unreported exception XXX; must be caught or declared” → XXX 是受检异常
- 编译通过,但运行时可能崩溃(比如访问 null 对象、数组越界)→ 基本是运行时异常
- 注意:new RuntimeException("msg") 仍是运行时异常,编译器完全不管
按设计意图决定要不要捕获
区分不只是为了过编译,更是为了明确责任归属:
- 受检异常多由外部不确定性引起(文件丢失、网络中断、数据库不可达),程序通常可以恢复。建议:要么 try-catch 后重试/提示/降级,要么在方法签名中 throws 交由上层决策
- 运行时异常几乎都源于逻辑疏漏(没判空、下标算错、参数非法)。建议:优先用 if 校验、Optional、断言等方式预防,而不是 catch 住再吞掉;静默忽略 NullPointerException 等于主动丢掉调试线索
别被名字或 throw 方式带偏
异常类型不由你“怎么抛”决定,而由它“是谁”决定:
- UnsupportedEncodingException 名字像错误,但它是 IOException 子类 → 受检异常
- 你自己写的 MyBusinessException extends Exception → 受检异常
- 你自己写的 MyParamException extends RuntimeException → 运行时异常,哪怕叫“Exception”也一样
- throw new IOException() 和 throw new RuntimeException() 的处理义务完全不同,和 throw 动作本身无关
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










