Java异常处理核心在于分类逻辑(受检/非受检/Error)、处理意图(应对外部不确定性/修复逻辑错误/记录告警)和真实场景取舍(throws声明契约、throw主动抛出、自定义异常语义清晰)。

先搞清异常分类的本质区别
不是记“哪些是运行时异常”,而是理解:编译器要不要管你。
-
受检异常(Checked):比如
IOException、SQLException。编译器强制你表态——要么try-catch拦下来自己消化,要么用throws推给上层。它代表的是外部不确定性(文件可能不存在、网络可能断开),程序本身无法预判,但可以合理应对。 -
非受检异常(Unchecked):即
RuntimeException及其子类,如NullPointerException、IllegalArgumentException。编译器放行,因为它们反映的是代码写错了——空指针、数组越界、传了非法参数。理想做法是修复逻辑,而不是盲目捕获。 -
Error:如
OutOfMemoryError、StackOverflowError。JVM 级崩溃,程序基本无力回天,不建议 catch,更不该重试或恢复;日志记录 + 监控告警才是正解。
重点看 try-catch-finally 的实际行为
面试常问“finally 一定执行吗?”“catch 里 return,finally 还走吗?”,核心是理解 JVM 的执行契约:
-
finally块在try或catch执行完毕后、方法真正退出前执行,哪怕前面有 return、break、continue,甚至 catch 里抛新异常,它都跑。 - 唯一不执行的情况:JVM 直接退出(如
System.exit(0))、线程被 kill、或 finally 里发生未捕获的严重错误(极少见)。 -
finally中如果有return,它会覆盖 try/catch 中的返回值——这是很多坑的来源,日常开发中应避免在 finally 里写 return。
关注 throws 和 throw 的使用边界
不是“能加就加”,而是看责任归属:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
throws是声明契约:告诉调用者“我这里可能出问题,你来决定怎么兜底”。适合底层工具方法(如读文件、连数据库),把选择权交给业务层。 -
throw是主动出击:用于校验失败时抛出自定义异常,或包装底层异常为业务可读的异常(如把SQLException转成AccountNotFoundException)。 - 注意:子类重写父类方法时,不能抛出比父类更宽泛的受检异常(违反里氏替换),但可以抛更具体的,或不抛。
自定义异常不是炫技,而是为了语义清晰
面试官想看你是否理解“异常即文档”:
立即学习“Java免费学习笔记(深入)”;
- 继承
Exception→ 表示调用方必须处理(受检);继承RuntimeException→ 表示属于编程错误或业务规则违例(非受检)。 - 构造函数至少提供
String message和Throwable cause两个版本,方便链式异常传递。 - 命名要见名知意,如
InsufficientBalanceException比BusinessException更有价值。

















