自定义异常
自定义异常用于表达业务特定的错误类型。
为什么需要自定义异常
业务特定错误
内置异常类无法表达特定业务含义。
Java
// 使用内置异常,语义不清晰
throw new IllegalArgumentException("余额不足");
// 使用自定义异常,语义明确
throw new InsufficientBalanceException("账户余额不足,无法完成转账");
异常分类管理
自定义异常便于分类处理不同业务错误。
Java
try {
// 业务操作
} catch (InsufficientBalanceException e) {
// 处理余额不足
} catch (AccountFrozenException e) {
// 处理账户冻结
} catch (BusinessException e) {
// 处理其他业务异常
}
自定义异常创建
继承Exception(检查型异常)
Java
// 检查型自定义异常
public class BusinessException extends Exception {
public BusinessException() {
super();
}
public BusinessException(String message) {
super(message);
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
}
继承RuntimeException(非检查型异常)
Java
// 非检查型自定义异常(推荐)
public class BusinessException extends RuntimeException {
public BusinessException() {
super();
}
public BusinessException(String message) {
super(message);
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
}
推荐继承RuntimeException,避免强制throws声明。
自定义异常示例
业务异常基类
Java
public class BusinessException extends RuntimeException {
private String errorCode; // 错误码
public BusinessException(String message) {
super(message);
}
public BusinessException(String errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
public String getErrorCode() {
return errorCode;
}
}
具体业务异常
Java
// 余额不足异常
public class InsufficientBalanceException extends BusinessException {
public InsufficientBalanceException(String message) {
super(message);
}
public InsufficientBalanceException(double balance, double required) {
super("余额不足,当前余额:" + balance + ",需要:" + required);
}
}
// 账户冻结异常
public class AccountFrozenException extends BusinessException {
public AccountFrozenException(String accountId) {
super("账户已冻结: " + accountId);
}
}
使用自定义异常
抛出自定义异常
Java
public void transfer(String accountId, double amount) {
Account account = getAccount(accountId);
if (account == null) {
throw new AccountNotFoundException(accountId);
}
if (account.isFrozen()) {
throw new AccountFrozenException(accountId);
}
if (account.getBalance() < amount) {
throw new InsufficientBalanceException(account.getBalance(), amount);
}
// 执行转账
}
捕获自定义异常
Java
try {
transfer("A001", 1000);
System.out.println("转账成功");
} catch (AccountNotFoundException e) {
System.out.println("账户不存在: " + e.getMessage());
} catch (AccountFrozenException e) {
System.out.println("账户已冻结");
} catch (InsufficientBalanceException e) {
System.out.println("余额不足: " + e.getMessage());
} catch (BusinessException e) {
System.out.println("业务异常: " + e.getMessage());
}
自定义异常最佳实践
构造方法设计
提供多种构造方法满足不同场景。
Java
public class CustomException extends RuntimeException {
// 无参构造
public CustomException() {
super();
}
// 消息构造
public CustomException(String message) {
super(message);
}
// 原因异常构造(异常链)
public CustomException(String message, Throwable cause) {
super(message, cause);
}
// 原因异常构造(无消息)
public CustomException(Throwable cause) {
super(cause);
}
}
添加自定义属性
Java
public class OrderException extends BusinessException {
private String orderId; // 订单ID
private OrderStatus status; // 订单状态
public OrderException(String orderId, OrderStatus status, String message) {
super(message);
this.orderId = orderId;
this.status = status;
}
public String getOrderId() {
return orderId;
}
public OrderStatus getStatus() {
return status;
}
}
异常层次结构
Java
// 业务异常基类
public class BusinessException extends RuntimeException { }
// 用户相关异常
public class UserException extends BusinessException { }
public class UserNotFoundException extends UserException { }
public class UserDisabledException extends UserException { }
// 订单相关异常
public class OrderException extends BusinessException { }
public class OrderNotFoundException extends OrderException { }
public class OrderCancelledException extends OrderException { }
检查型与非检查型选择
选择标准
| 场景 | 推荐类型 | 原因 |
|---|---|---|
| 业务逻辑错误 | RuntimeException | 调用者无法恢复 |
| 参数校验错误 | RuntimeException | 编程错误 |
| 外部资源问题 | Exception | 调用者可恢复处理 |
| 流程控制需要 | Exception | 强制调用者处理 |
实际建议
Java
// 推荐:继承RuntimeException
public class BusinessException extends RuntimeException {
// 不强制throws,使用灵活
}
// 特殊需要:继承Exception
public class DatabaseException extends Exception {
// 强制调用者处理,确保不忽略
}
要点总结
- 自定义异常用于表达业务特定错误
- 继承Exception创建检查型异常
- 继承RuntimeException创建非检查型异常(推荐)
- 提供多种构造方法(无参、消息、原因)
- 可添加自定义属性(错误码、订单ID等)
- 建立异常层次结构便于分类处理
- 业务逻辑错误推荐RuntimeException
- 外部资源问题可使用Exception
- 异常命名以Exception结尾
- 语义清晰,便于定位问题
📝 发现内容有误?点击此处直接编辑