java中tostring默认只输出类名和哈希码,需手动重写并递归调用子对象tostring;应空值检查、避免循环引用、禁用耗时操作,并过滤敏感字段以确保调试与日志的稳定性与安全性。

Java 中 toString 方法默认只输出对象的类名和哈希码,对嵌套对象不做任何展开。若要清晰展示嵌套结构,需手动重写 toString,并递归或显式调用子对象的 toString 方法。
手动拼接嵌套字段
最直接的方式是在重写 toString 时,逐个访问嵌套对象,并调用其 toString(前提是该嵌套类也合理实现了该方法)。
- 避免直接打印
Object引用(如com.example.Address@1a2b3c),应显式调用address.toString() - 对可能为
null的嵌套对象做空值检查,防止NullPointerException - 使用
String.format或StringBuilder提升可读性和性能
借助工具类简化实现
Apache Commons Lang 的 ToStringBuilder 和 Jackson 的 ObjectMapper 可自动处理嵌套结构,但行为有差异:
-
ToStringBuilder.reflectionToString(this)会递归反射获取所有字段(含私有),但不控制深度,可能引发无限循环(如双向引用) -
ObjectMapper.writeValueAsString(this)输出 JSON 格式,天然支持嵌套,但需确保对象可序列化且无循环引用(可配SimpleModule或@JsonManagedReference) - Lombok 的
@ToString注解默认递归调用嵌套对象的toString,可用includeFieldNames = true和callSuper = true增强可读性
规避循环引用与性能陷阱
嵌套对象常存在父子/双向引用(如 Order ↔ Customer),直接递归会导致栈溢出或无限输出。
- 在自定义
toString中对已访问对象做标识(如用ThreadLocal<set>></set>记录路径) - 工具类中启用循环检测:Lombok 支持
@ToString(of = {"name", "address"})显式指定字段;Jackson 可配置SerializationFeature.FAIL_ON_SELF_REFERENCES - 避免在
toString中执行耗时操作(如数据库查询、文件读取),它可能被日志框架频繁调用
保持一致性与可维护性
toString 是调试和日志的关键入口,输出格式应稳定、可预期。
- 字段顺序尽量与构造参数或业务逻辑一致,便于快速定位
- 敏感字段(如密码、token)不应出现在
toString中,即使嵌套对象包含它们,也应在对应类中过滤 - 测试时验证嵌套层级输出是否符合预期,尤其关注
null、空集合、特殊字符等边界情况
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











