自定义异常需继承Exception(检查型)或RuntimeException(非检查型);检查型异常强制处理,适用于文件不存在等可恢复场景,需提供无参、String、Throwable及完整构造方法;非检查型异常用于逻辑错误,业务异常推荐检查型。

在Java中,自定义异常类需要继承 Exception 或其子类(如 RuntimeException),核心是明确异常类型(检查型/非检查型)并提供合适的构造方法。
继承 Exception 实现检查型异常
继承 Exception 类创建的异常属于检查型异常(Checked Exception),编译器强制要求调用方处理(try-catch 或 throws)。适合表示可预期、应主动恢复的异常场景,如文件不存在、网络超时等。
推荐做法:
- 提供无参构造方法
- 提供带 String 消息的构造方法(调用
super(message)) - 提供带 Throwable cause 的构造方法(支持异常链)
- 提供完整参数构造方法(message + 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)。这类异常属于非检查型异常(Unchecked Exception),常用于程序逻辑错误,如空指针、数组越界、自定义业务逻辑异常(如参数非法)。
注意:不要滥用非检查型异常掩盖本该显式处理的问题;业务层面的“异常状态”(如余额不足)更推荐用检查型异常,以保障调用方感知和处理。
异常继承关系的关键要点
Java 异常体系根类是 Throwable,分为两大分支:
- Error:JVM 错误(如 OutOfMemoryError),一般不捕获、不继承
-
Exception:程序可处理的异常,再细分为:
- Checked Exception:除 RuntimeException 及其子类外的所有 Exception 子类
- Unchecked Exception:RuntimeException 及其所有子类
自定义异常时,继承位置决定其是否受编译检查——只要不是 RuntimeException 的子孙类,就是检查型异常。
使用建议与注意事项
实际开发中需注意:
- 避免直接继承 Exception 做运行时异常;应继承 RuntimeException
- 为异常类添加有意义的类名(通常以 Exception 结尾)
- 必要时重写
toString()或增加业务字段(如错误码、时间戳),但需保持序列化兼容性 - 在 throws 声明或 catch 中使用时,遵循里氏替换原则:父类异常声明可被子类异常实现替代










