应继承 runtimeexception 并提供4个标准构造方法,不添加字段、不实现 serializable,命名体现业务域且以 exception 结尾。

编写符合阿里巴巴 Java 开发手册(《阿里巴巴 Java 开发规约》)的自定义异常 POJO,核心是继承 RuntimeException、提供规范构造方法、避免冗余字段、不实现序列化接口。手册明确要求:业务异常应使用 unchecked 异常(即继承 RuntimeException),且自定义异常类应保持轻量、语义清晰、便于定位问题。
1. 继承 RuntimeException,不继承 Exception
阿里规约第 7 章「异常日志」明确指出:“推荐使用 RuntimeException 或其子类作为业务异常类型”。因为业务异常属于“可预期的、流程中主动抛出的异常”,不应强制调用方 try-catch,避免代码臃肿。
- ✅ 正确:public class BizException extends RuntimeException
- ❌ 错误:public class BizException extends Exception(需声明 throws,违反规约)
- ❌ 错误:public class BizException extends IOException(属于受检异常体系,不适用业务场景)
2. 提供标准构造方法(4 种必须)
为兼容主流日志框架(如 Logback、SLF4J)和 IDE 自动补全,需完整提供以下构造方法(顺序与 JDK 内置异常一致):
- 无参构造:public BizException()
- 带 message 构造:public BizException(String message)
- 带 cause 构造:public BizException(Throwable cause)
- 带 message 和 cause 构造:public BizException(String message, Throwable cause)
注意:message 应简洁明确,建议包含业务上下文关键词(如“订单”“库存”“用户ID=xxx”),但不要拼接敏感信息或堆栈;cause 必须调用 super(cause) 传递,确保异常链完整。
3. 不添加额外字段,禁止序列化相关代码
阿里规约强调“异常类不应有属性,更不应实现 Serializable 接口”。原因有三:
- 异常本质是信号,不是数据载体;加字段易被误用为 DTO
- 序列化 ID(serialVersionUID)和 writeObject/readObject 方法会引入维护负担
- 分布式场景下异常跨服务传播时,字段可能引发版本兼容或安全问题
✅ 正确写法:类体为空,仅含构造方法;
❌ 错误写法:private String errorCode; private Long userId; private static final long serialVersionUID = 1L;
4. 命名与包路径规范
命名体现业务域和异常性质,包路径与对应 service 层对齐:
- 类名以 Exception 结尾,如 OrderCreateException、InventoryLockFailException
- 包路径建议:com.xxx.yyy.exception(与 service 包同级,避免放在 dto 或 model 下)
- 避免泛化命名:如 MyException、BaseException、GlobalException(语义模糊,违反规约“异常命名应见名知意”)
示例精简代码:
package com.alibaba.trade.exception;<br><br>public class OrderCreateException extends RuntimeException {<br> public OrderCreateException() {<br> super();<br> }<br><br> public OrderCreateException(String message) {<br> super(message);<br> }<br><br> public OrderCreateException(Throwable cause) {<br> super(cause);<br> }<br><br> public OrderCreateException(String message, Throwable cause) {<br> super(message, cause);<br> }<br>}










