如何在Java中自定义异常_Java自定义异常类编写方法说明

Java自定义异常需继承Exception(检查型,强制处理)或RuntimeException(非检查型,无需强制处理),并提供无参、String参数、String+Throwable参数构造方法,类名以Exception结尾,消息应具体可读,支持异常链和业务字段扩展。

在Java中自定义异常,核心是继承 ExceptionRuntimeException 类,并提供合适的构造方法。是否需要检查(checked)取决于你继承的是哪个父类。

继承 Exception 实现检查型异常

这类异常必须在编译期处理(try-catch 或 throws),适合表示可预期、应主动恢复的业务问题,比如“余额不足”“用户名已存在”。

  • 新建类,继承 Exception
  • 至少提供两个构造方法:无参构造 + 带 String 参数的构造(调用 super(msg))
  • 可选:增加带 Throwable cause 的构造,支持异常链

示例:

public class InsufficientBalanceException extends Exception {
    public InsufficientBalanceException() {
        super("账户余额不足");
    }
    public InsufficientBalanceException(String message) {
        super(message);
    }
    public InsufficientBalanceException(String message, Throwable cause) {
        super(message, cause);
    }
}

继承 RuntimeException 实现非检查型异常

这类异常无需强制处理,适合表示程序逻辑错误或不可恢复的意外,比如“参数为空”“状态非法”。

  • 继承 RuntimeException,不是 Exception
  • 同样建议提供常用构造方法(String、String+Throwable)
  • 抛出时不用声明 throws,调用方更自由

示例:

public class InvalidStatusException extends RuntimeException {
    public InvalidStatusException(String status) {
        super("非法状态: " + status);
    }
}

使用时注意的关键点

  • 异常类名以 Exception 结尾,语义清晰(如 PaymentFailedException)
  • 消息内容应具体、可读,避免空字符串或纯代码(如 "error 1001")
  • 如果涉及业务上下文,可在异常类中添加字段(如 orderId、userId),并提供 getter
  • 不要吞掉原始异常——用 cause 构造器保留堆栈,便于排查

什么时候该自定义,而不是直接 throw new RuntimeException?

  • 需要区分异常类型做不同处理(比如对支付失败重试,对参数错误直接返回)
  • 团队协作中统一错误码/日志格式,靠自定义类封装逻辑
  • 框架(如 Spring)能基于异常类型自动映射 HTTP 状态码
  • 想让调用方明确感知某类业务风险,而非笼统的运行时错误

基本上就这些。自定义异常不复杂但容易忽略语义和使用场景,关键是让异常真正“说话”。