RuntimeException 本身不简化复杂度,但有意识利用其语义特性可重构逻辑:用卫语句替代嵌套校验、统一异常处理、配合断言强化意图,从而降低圈复杂度;但仅适用于编程错误,不适用于业务异常。

RuntimeException 本身不是简化代码复杂度的手段,而是一种异常类型。真正能简化复杂度的,是**有意识地利用 RuntimeException 的语义特性来重构逻辑**——比如用它替代冗长的校验分支、避免层层嵌套的 if-else、统一错误出口,从而让主流程更线性、更专注。
用 RuntimeException 替代防御式校验嵌套
当多个前置条件必须满足才能执行核心逻辑时,传统写法容易形成“金字塔式”嵌套:
- 先判空,再判范围,再判状态,再判权限……
- 每层 if 都缩进一层,可读性骤降,维护成本升高
改用 RuntimeException(如 IllegalArgumentException、IllegalStateException)配合卫语句(Guard Clause),立刻扁平化:
- if (obj == null) throw new IllegalArgumentException("对象不能为空");
- if (id < 0) throw new IllegalArgumentException("ID 不能为负数");
- if (!user.isActive()) throw new IllegalStateException("用户未激活");
- 后续代码直接写业务逻辑,无缩进、无 else
统一错误处理,剥离异常逻辑
把分散在各处的 try-catch 或 if-throw 拆解出来,集中到统一的异常处理器(如 Spring 的 @ControllerAdvice),主业务方法就不再掺杂错误分支:
- Service 方法只关注“做什么”,不写“出错了怎么办”
- 校验失败抛 RuntimeException → 由全局处理器转成 HTTP 400 或统一错误码
- 代码行数减少,分支数下降,圈复杂度(Cyclomatic Complexity)显著降低
配合 Optional 或断言,强化意图表达
RuntimeException 能让“非法状态不可达”这一设计意图显性化:
- 用 Objects.requireNonNull() 替代手动 null 判断,失败时自动抛 NPE(RuntimeException 子类)
- 用 Assert.notNull()(Spring)、Preconditions.checkArgument()(Guava)等断言工具,语义清晰且自带异常信息
- 比起 return false / return null,抛 RuntimeException 更明确地表示“这不是正常路径,程序不该走到这里”
慎用:不是所有地方都适合
RuntimeException 适用于编程错误或不可恢复的非法输入,不适用于业务规则导致的预期失败(如“余额不足”应返回 Result 或 BusinessException):
- 抛 RuntimeException = 告诉调用方:“你用错了,请改代码”
- 返回业务异常 = 告诉调用方:“这次操作没成功,但系统没问题,可以重试或引导用户”
- 混用会导致错误分类混乱,反而增加理解成本

















