Java 异常

一、异常的第一性原理

1.1 异常的本质

在任何编程语言中,异常机制的本质只有一句话:

异常 = 跨函数边界的错误传播机制

它解决的根本问题是:

当程序执行路径上出现“非常规情况”时,如何优雅地打断正常控制流,并把错误信息传递给合适的处理者。


1.2 为什么需要异常

在异常机制出现之前,程序处理错误主要依赖:

这些方式的本质问题是:

错误处理逻辑会污染正常业务逻辑

异常机制的价值在于:

方式关注点
返回值调用方必须显式判断
异常将“错误处理”与“业务逻辑”解耦

异常让程序结构从:

业务逻辑 + 大量 if 判断

变为:

业务逻辑主路径+ 独立的异常处理路径

1.3 异常的三大核心特征

异常机制在本质上提供了三个能力:

  1. **中断当前流程**
  2. **携带错误上下文**
  3. **跨层传播**

这三点共同决定了:

异常不是“错误本身”,而是“错误处理的组织机制”。


二、Java 异常模型

2.1 Java 的异常类型体系

在 Java 中,异常体系是一棵类型树:

Object └── Throwable     ├── Error     └── Exception          ├── Checked Exception          └── RuntimeException

两个根概念

类型本质
ErrorJVM 层面无法恢复的问题
Exception程序逻辑层面可处理的问题

2.2 Checked vs Unchecked 的本质

Java 将异常分为两类:

维度Checked ExceptionRuntime Exception
编译器要求必须处理可不处理
设计意图强制调用方感知表示程序缺陷
可恢复性更偏可恢复更偏不可恢复

核心区别不是“能否处理”,而是:

是否需要通过类型系统强制上层关注


2.3 Java 异常体系的设计哲学

Java 的异常模型背后有两个核心设计思想:

  1. **让业务代码更干净**
  2. **让错误传播更显式**

但实践中也暴露出问题:

因此在工程实践中:

RuntimeException 往往成为主流选择


三、异常的多维度认知模型

为了避免“分类混乱”,需要把异常放在不同维度下理解。


3.1 语法维度

这是:

Java 语言机制层面的划分


3.2 来源维度

来源示例
业务异常未授权、余额不足
系统异常空指针、数组越界
基础设施异常网络超时、数据库异常

3.3 可恢复性维度

类型策略
可恢复重试、降级
不可恢复快速失败

3.4 处理边界维度

范围方式
模块内部直接处理
服务边界转换为错误码
跨系统封装为 Result

四、异常处理的核心原则

4.1 异常处理的本质矛盾

异常机制的最大问题是:

异常处理是复杂度的放大器

不合理的异常设计,会让系统变得:


4.2 三条核心原则

原则一:就近处理


原则二:语义稳定

对外接口的异常必须稳定:

接口的异常变化 = 接口契约变化


原则三:最小惊讶


五、工程实践模型

5.1 分层异常架构

一个稳定系统中的异常结构应为:

Controller   ↓Service -> BusinessException   ↓DAO -> InfrastructureException

5.2 异常转换模式

不同层次之间应进行异常转换:

层次策略
DAO转为数据访问异常
Service转为业务异常
API转为错误码

5.3 Result 模式

在跨系统调用中:

❗ 不应该直接抛异常

而应该使用:

Result<T> {  code  message  data}

原因:

  1. 防止调用方漏捕获
  2. 更利于序列化
  3. 更稳定的接口契约

六、异常使用规范

6.1 try-catch 的本质

try {    // 正常路径} catch (SpecificException e) {    // 异常路径} finally {    // 资源清理}

其本质是:

把控制流一分为二:


6.2 捕获原则


6.3 finally 语义

finally 的语义是:

资源一致性保证,而非业务逻辑承载

因此:


七、异常的性能本质

7.1 两个层次的开销

行为开销
try-catch 本身很小
真正抛异常很大

7.2 为什么异常昂贵

因为抛异常时 JVM 需要:

这是一个“重型操作”。


7.3 工程启示


八、系统设计中的异常策略

8.1 三类异常策略

类型处理方式
业务异常明确返回给用户
可恢复异常重试/降级
不可恢复异常快速失败

8.2 全局异常处理

推荐统一异常网关:

GlobalExceptionHandler  ↓日志记录  ↓统一响应

8.3 可观测性

异常处理必须配套:


九、反模式清单

以下都是常见的异常反模式:


十、总结:异常设计方法论

可以用一句话总结:

异常设计 = 复杂度管理

一个优秀的异常设计应该做到:

关联内容(自动生成)