在 java 异常处理中,获取原始异常最直接的方法是使用 throwable 类的 getcause() 方法。当异常被包装(wrap)时,原始异常会作为参数传递给新异常的构造函数,并通过 initcause() 机制保存下来。调用 getcause() 即可返回这个被包装的原始异常对象,从而保留完整的错误链路。

如何手动包装并获取异常
通过构造函数的第二个参数传入原始异常,即可实现手动包装。调用 getCause() 能准确拿到被包裹的异常实例。

import java.io.IOException;
public class ExceptionDemo {
public static void main(String[] args) {
try {
doSomething();
} catch (Exception e) {
// 获取原始异常
Throwable cause = e.getCause();
if (cause != null) {
System.out.println("原始异常类型: " + cause.getClass().getSimpleName());
System.out.println("原始异常信息: " + cause.getMessage());
}
}
}
private static void doSomething() throws Exception {
try {
throw new IOException("底层 IO 失败");
} catch (IOException ex) {
// 手动包装异常
throw new RuntimeException("业务逻辑失败", ex);
}
}
}自动捕获时的异常链行为
在 catch 块中直接抛出当前异常对象而不指定原因时,getCause() 将返回 null。这种行为会导致异常链断裂,丢失堆栈跟踪中的原始上下文信息。
立即学习“Java免费学习笔记(深入)”;

import java.io.IOException;
public class BrokenChainDemo {
public static void main(String[] args) {
try {
doBroken();
} catch (Exception e) {
Throwable cause = e.getCause();
if (cause == null) {
System.out.println("异常链已断裂,无法获取原始异常");
}
}
}
private static void doBroken() throws Exception {
try {
throw new IOException("底层 IO 失败");
} catch (IOException ex) {
// 错误做法:未传递 cause
throw new RuntimeException("业务逻辑失败");
}
}
}深层嵌套异常的遍历方法
当异常经过多层包装时,单次调用 getCause() 只能获取上一层的异常。为了获取最原始的异常,需要编写循环或递归逻辑,沿着 cause 链一直向下查找,直到 getCause() 返回 null 为止。


















