自定义异常必须显式调用super(message)等父类构造器才能正确传递异常信息;否则getMessage()返回null。常见写法包括单参、双参(含cause)、无参及格式化构造器,且不可重写getMessage()。

Java 中自定义异常继承父类(如 Exception 或 RuntimeException)时,异常信息(即 message)是通过调用父类构造方法传递的。关键在于:**必须在子类构造器中显式调用 super(message) 或其他带 message 参数的父类构造器**,否则父类无法拿到你想要的提示文本。
1. 正确传递 message 的基本写法
自定义异常类通常只需提供一个或多个构造器,并在其中把 message 传给父类:
- 继承
Exception(检查型异常):
public class UserNotFoundException extends Exception {
public UserNotFoundException(String message) {
super(message); // ✅ 把 message 交给父类处理
}
}
- 使用时:
throw new UserNotFoundException("用户 ID 为 123 的记录不存在");,后续通过e.getMessage()就能拿到该字符串。
2. 支持 cause(异常链)的进阶写法
如果还想保留原始异常(比如数据库查询失败导致的 SQLException),可以同时传 message 和 cause:
public class UserNotFoundException extends Exception {
public UserNotFoundException(String message, Throwable cause) {
super(message, cause); // ✅ 同时设置 message 和 cause
}
}
- 这样既保留了可读的业务提示,又不丢失底层错误堆栈,便于排查。
- 调用示例:
throw new UserNotFoundException("查不到用户", sqlEx);
3. 多参数构造器的常见组合
实际开发中常补充无参、仅 cause、或带格式化参数的构造器,提升易用性:
立即学习“Java免费学习笔记(深入)”;
public class UserNotFoundException extends Exception {
public UserNotFoundException() {
super("用户未找到");
}
public UserNotFoundException(String message) {
super(message);
}
public UserNotFoundException(String message, Throwable cause) {
super(message, cause);
}
// 支持格式化,如:new UserNotFoundException("用户 %s 不存在", "alice")
public UserNotFoundException(String format, Object... args) {
super(String.format(format, args));
}
}
4. 注意事项
- 如果不写任何构造器,编译器会提供默认无参构造器,但此时
getMessage()返回null—— 因为没调用父类带 message 的构造器。 - 父类
Exception本身不保存 message 字段,而是由其父类Throwable管理,super(message)最终是把字符串存到Throwable的私有字段里。 - 不要在子类中重写
getMessage()来“手动返回”,这会绕过标准机制,影响日志、框架解析等行为。


















