Java业务异常应继承RuntimeException,包含errorCode、message和userMessage字段,配合@ControllerAdvice统一响应为标准JSON并记录WARN日志。

在 Java 中,通过自定义异常(Custom Exception)实现业务异常处理,核心是让异常携带明确的业务语义、便于分类捕获、支持统一响应和日志追踪。关键不在于“抛出异常”,而在于“为什么抛、抛给谁、怎么收”。
继承合适的异常类型:RuntimeException 还是 Exception?
业务异常通常属于「预期内但非正常流程」的情况(如余额不足、用户已存在、参数校验失败),应继承 RuntimeException,避免强制 try-catch,保持调用方代码简洁:
- 用 RuntimeException 的子类 → 不检查异常(unchecked),适合业务规则中断,如
InsufficientBalanceException - 用 Exception 的子类 → 检查异常(checked),仅当调用方「必须显式处理」时使用(如对接外部支付接口超时需重试),但业务层慎用,易导致模板式 try-catch 泛滥
自定义异常类要包含哪些必要字段?
一个实用的业务异常至少应提供:错误码、错误消息、可选上下文参数,方便前端展示、日志定位、后续扩展:
-
errorCode:全局唯一字符串或数字码(如
"BUSI_001"),避免硬编码,建议集中管理(枚举类) -
message:面向开发/运维的提示(如
"账户余额不足以完成本次交易"),不直接返回给前端 -
tips 或 userMessage:可选字段,用于返回给前端的友好提示(如
"余额不足,请先充值") -
构造函数支持格式化消息:利用
String.format()或 SLF4J 风格占位符,例如:
public BusinessException(String code, String format, Object... args) {<br> super(String.format(format, args));<br> this.errorCode = code;<br>}
配合全局异常处理器统一响应
自定义异常只有被统一拦截并转化为标准 API 响应,才算真正落地。Spring Boot 中常用 @ControllerAdvice + @ExceptionHandler:
立即学习“Java免费学习笔记(深入)”;
- 针对你的自定义异常(如
BusinessException)单独写一个@ExceptionHandler方法 - 返回标准化 JSON(如
{"code": "BUSI_001", "message": "余额不足", "data": null}) - 记录带 errorCode 和堆栈的日志(注意:业务异常一般不打 ERROR 级别,用 WARN 更合理)
- 可补充对
IllegalArgumentException、NullPointerException等常见运行时异常的兜底处理
实际使用示例:转账场景
在 service 方法中,不写 if (balance ,而是:
- 定义异常:
public class InsufficientBalanceException extends BusinessException { ... } - 业务判断:
if (account.getBalance().compareTo(amount) < 0) {<br> throw new InsufficientBalanceException("BUSI_201", "账户 {} 余额不足,需 {}, 当前为 {}",<br> account.getId(), amount, account.getBalance());<br>} - 前端收到统一结构响应,后台日志自动带上 errorCode 和关键变量值,排查时一目了然


















