推荐使用日志框架原生支持(如SLF4J的log.error(“msg”, e))记录异常,避免printStackTrace();手动处理需用getStackTrace()+toString()拼接;重抛异常须传cause或用throw e保留原始堆栈。
直接调用 printStackTrace() 最快但不灵活
最常见做法是捕获异常后调用 e.printStackTrace(),它会把堆栈信息输出到 System.err。适合开发调试,但无法控制输出位置或格式,线上环境容易干扰日志结构。
- 不推荐在生产代码中使用,尤其不能和日志框架混用(比如 SLF4J +
printStackTrace()会导致日志行错乱) - 如果必须用,建议重定向到
PrintWriter写入字符串:new StringWriter().getBuffer().toString(),便于后续处理 - 注意:该方法不抛出异常,也不返回值,纯副作用操作
用 Exception.toString() 和 getStackTrace() 手动拼接
当需要自定义输出格式(比如只取前 3 层、过滤某些类名、加时间戳),就得手动处理堆栈元素。核心是 e.getStackTrace() 返回 StackTraceElement[] 数组。
-
e.toString()给出异常类型 + 消息,如java.lang.NullPointerException: Cannot invoke "String.length()" because "s" is null - 遍历
e.getStackTrace()可逐行获取类名、方法名、文件名和行号,适合做脱敏(如隐藏内部包路径) - 性能上比
printStackTrace()略低,但可控性强;注意不要在高频路径中反复拼接长堆栈
Logback / Log4j2 中正确记录异常堆栈
主流日志框架对异常有原生支持,传入 Throwable 参数即可自动展开堆栈,无需手动处理。