Java中重新抛出异常时应使用带Throwable cause参数的构造方法包装原始异常,如new RuntimeException("msg", e),自定义异常需显式调用super(message, cause),否则cause丢失导致getCause()返回null。

在Java中,重新抛出异常时包装为新异常并传递原始异常作为cause,核心是使用带Throwable cause参数的构造方法,并确保新异常的构造函数支持cause链。
选择支持cause的异常构造器
不是所有异常类都默认支持cause。必须显式调用带Throwable参数的构造器,例如:
new RuntimeException("业务失败", originalException)new IllegalArgumentException("参数非法", e)-
new CustomException("自定义错误", e)(前提是CustomException提供了相应构造器)
确保自定义异常正确委托cause
如果定义自己的异常类,需在构造器中显式调用父类含cause的构造器:
public class ServiceException extends Exception {
public ServiceException(String message, Throwable cause) {
super(message, cause); // 关键:把cause传给父类
}
}
否则即使传了cause,也会丢失堆栈链,导致getCause()返回null。
立即学习“Java免费学习笔记(深入)”;
避免常见错误:不要只传message
以下写法会丢失原始异常信息:
-
throw new RuntimeException("处理失败");—— 没传cause,原始异常彻底丢失 -
throw new RuntimeException(e.getMessage());—— 只取了message,没保留堆栈和cause -
throw new RuntimeException(e);—— 虽然传了e,但此时e成了message字符串(因为调用的是String构造器),不是cause
运行时检查cause是否生效
可通过getCause()和printStackTrace()验证:
-
e.getCause() == originalException应为true -
e.printStackTrace()输出中应包含原始异常的完整堆栈(标记为“Caused by:”)


















