Java自定义异常需继承Exception或RuntimeException,并提供含Throwable参数的构造函数,通过super(cause)或super(message, cause)调用父类构造器以支持异常链;否则cause为null。

Java 中给自定义异常添加父异常构造函数,核心是让自定义异常类继承 Exception(或其子类如 RuntimeException),并在自己的构造方法中显式调用父类对应构造函数,尤其是接收 Throwable 或 String + Throwable 的构造函数,从而支持传递原始异常(cause)。
继承标准异常类并复用父类构造函数
自定义异常必须继承 Exception 或 RuntimeException。为支持“异常链”(即保留原始异常作为 cause),需提供接收 Throwable 参数的构造方法,并用 super(cause) 调用父类构造函数:
public class ValidationException extends Exception {
// 无参构造
public ValidationException() {
super();
}
// 仅消息
public ValidationException(String message) {
super(message);
}
// 仅原因(最常用:保留原始异常)
public ValidationException(Throwable cause) {
super(cause); // ← 关键:把 cause 传给父类,自动设置 getCause()
}
// 消息 + 原因(推荐:兼顾可读性与异常链)
public ValidationException(String message, Throwable cause) {
super(message, cause); // ← 同样关键
}
}
正确使用 cause 构造函数的关键细节
只有调用 super(cause) 或 super(message, cause),JVM 才会将传入的 Throwable 设置为该异常的 cause,后续可通过 getCause() 获取、printStackTrace() 显示完整链路。若只写 this(message); 或漏掉 super 调用,cause 将为 null。
- 不要在构造函数里手动调用
initCause()——super(cause)已完成初始化 - 若父类是
RuntimeException,同样适用:super(cause)有效且保持 unchecked 特性 - 所有构造函数都应覆盖,否则可能丢失异常上下文(例如只实现
ValidationException(String),却用new ValidationException(e)编译不通过)
实际抛出时如何传递原始异常
捕获底层异常后,用带 cause 的构造函数包装它,形成清晰的异常层级:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
try {
parseJson(input);
} catch (JsonParseException e) {
throw new ValidationException("JSON 格式非法", e); // ← e 成为 cause
}
这样调用方既能看到业务语义(“JSON 格式非法”),又能通过 e.getCause() 拿到原始 JsonParseException 分析根本原因。
检查是否成功设置 cause
可通过以下方式验证:
-
exception.getCause() != null→ 返回原始异常对象 -
exception.toString()输出包含 “Caused by: …” 行 -
exception.printStackTrace()显示完整嵌套堆栈

















