重写 toString() 是为了让异常输出包含类型、错误码、消息、时间戳、traceId 等关键诊断信息;因默认 Throwable.toString() 仅返回类名和简略消息,缺乏业务上下文,不利于分布式系统排查。

自定义异常重写 toString() 方法,核心是让输出包含异常类型、自定义错误消息、以及关键诊断上下文(如错误码、时间、请求ID等),而不是仅依赖父类默认的简单格式。
为什么需要重写 toString
Java 中 Throwable.toString() 默认只返回 getClass().getName() + ": " + getLocalizedMessage(),不包含堆栈、业务字段或上下文信息。日志打印或调试时容易丢失关键线索,尤其在分布式系统中缺乏 traceId、errorCode 等诊断要素。
重写 toString 的实用写法
在自定义异常类中覆盖 toString(),把业务相关字段和标准信息结构化拼接。推荐包含:异常类名、错误码、简明消息、时间戳、可选上下文 ID(避免直接拼接堆栈——那属于 printStackTrace() 或日志框架职责)。
- 不要在
toString()中调用getStackTrace()或生成完整堆栈(性能差、易污染日志格式) - 优先使用
String.format或StringBuilder拼接,保证可读性和线程安全 - 保持输出简洁:一行文本,便于日志采集和 grep 分析
一个典型示例
假设定义了一个带错误码和 traceId 的业务异常:
立即学习“Java免费学习笔记(深入)”;
public class BizException extends RuntimeException {
private final int errorCode;
private final String traceId;
public BizException(int errorCode, String message, String traceId) {
super(message);
this.errorCode = errorCode;
this.traceId = traceId;
}
@Override
public String toString() {
return String.format("%s[errorCode=%d, traceId=%s, message=%s]",
getClass().getSimpleName(),
errorCode,
traceId != null ? traceId : "-",
getMessage() != null ? getMessage() : "N/A");
}
}
调用 new BizException(5001, "库存不足", "trc-abc123").toString() 输出:BizException[errorCode=5001, traceId=trc-abc123, message=库存不足]
配合日志使用的建议
toString() 只负责“摘要式”诊断信息;完整上下文应由日志框架捕获:
- 记录异常时,用
log.error("业务处理失败", e)—— 日志框架会自动附加堆栈 - 若需在日志中同时显示摘要和堆栈,可先打印
e.toString(),再单独输出e - 避免在
toString()里做耗时操作(如远程查配置、格式化日期对象),保持轻量


















