全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-08 6 分钟 ✍️ juanwangdev

自定义异常

自定义异常用于表达业务特定的错误类型。

为什么需要自定义异常

业务特定错误

内置异常类无法表达特定业务含义。

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结尾
  • 语义清晰,便于定位问题

📝 发现内容有误?点击此处直接编辑

← 上一篇 异常链与多重捕获
下一篇 → List 接口与实现
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库