printStackTrace()可快速定位异常源头,但生产环境应避免裸调用;获取结构化异常信息需用getMessage()、getCause()、getClass().getName()等方法;转堆栈为字符串推荐StringWriter+PrintWriter;自定义fillInStackTrace()需谨慎防止getStackTrace()返回null。
printStackTrace() 快速定位异常源头开发时遇到未捕获异常,最直接的方式是让 JVM 打印完整调用栈。这能立刻看到异常类型、消息和每层方法调用位置。
注意:printStackTrace() 默认输出到 System.err,不是 System.out,别在日志里只盯 stdout 而漏看它。
catch 块中调用 e.printStackTrace() 是最快捷的调试手段e.printStackTrace(new PrintWriter(stringWriter)) 捕获为字符串再交由日志框架处理printStackTrace(),它绕过日志级别控制且不易检索日志记录或 API 返回错误时,通常只需要结构化字段,而非整段堆栈。Java 异常对象本身提供稳定接口获取关键元数据。
getMessage() 只返回构造时传入的

getCause() 返回原始异常(如 SQLException 包裹的 IOException),需递归获取才完整;getClass().getName() 比 toString() 更可靠,避免被子类重写 toString 导致格式混乱。
e.getMessage() —— 不一定有内容,空指针或 IO 异常常返回 nulle.getCause() != null ? e.getCause().getMessage() : "no cause" —— 需判空,否则 NPEThrowableUtils.getRootCause(e)(Apache Commons Lang)或手动 while 循环遍历 getCause()
printStackTrace() 的副作用想把堆栈存进数据库、上报监控或拼进 JSON 日志,必须拿到字符串形式。不能依赖 printStackTrace() 的输出流副作用。
StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); String stackTrace = sw.toString();
这段代码是标准解法。注意 StringWriter 和 PrintWriter 都是内存对象,无 I/O 开销,但要确保 sw 不被意外复用(比如放在静态变量里)。
e.toString() 代替——它只含类名+message,没有堆栈行Arrays.toString(e.getStackTrace()),但格式难读,不推荐用于日志%throwable 即可,无需手动转字符串fillInStackTrace() 的陷阱有些场景需要隐藏真实堆栈(如安全限制)、或注入上下文(如请求 ID、用户 ID)。这时会重写 fillInStackTrace(),但极易出错。
常见误操作是直接 return this,导致后续 getStackTrace() 返回空数组;正确做法是保留原逻辑并追加元素,或使用 setStackTrace() 显式设置。
super(null) 构造,并在文档中标注“no stack trace”private final String traceId),而非篡改堆栈字符串fillInStackTrace() 后,getCause() 和 getSuppressed() 仍正常,但 getStackTrace() 可能为 null 或长度为 0,所有消费方都得做防御性判断