toString方法的核心用途是让对象以人类可读字符串形式表达自身状态,用于调试、日志和打印;默认实现返回“类名@哈希值”,需重写为ClassName{field1=value1, field2=value2}格式,避免副作用与耗时操作。

toString 方法的核心用途,是让对象能以人类可读的字符串形式表达自身状态。 它不是用来做数据转换或序列化的,而是为调试、日志、打印和简单展示服务的——当你用 System.out.println(obj) 或拼接字符串(如 "obj: " + obj)时,Java 默认就会调用它的 toString()。
为什么默认输出看起来像“类名@哈希值”?
因为所有类都继承自 Object,而 Object.toString() 的默认实现是:getClass().getName() + "@" + Integer.toHexString(hashCode())。比如 Person@1b6d3586。这个结果对开发者几乎没信息量,所以需要重写。
怎么写一个有用的 toString?
关键原则是:清晰、简洁、包含关键属性,不暴露敏感字段,避免递归调用(比如引用自身或循环引用的对象)。
- 用 IDE 自动生成(如 IntelliJ 的
Alt+Insert → toString)最省事,也符合惯例 - 手动写推荐格式:
ClassName{field1=value1, field2=value2},比如Person{name='张三', age=28} - 对可能为 null 的字段,建议用
Objects.toString(field, "null")防 NPE - 集合类字段如果内容多,可只显示大小(
items.size=5),避免日志刷屏
toString 不该做什么?
它不是序列化入口,别在里头写 JSON 生成、文件读写、网络请求等副作用操作;也不适合放复杂逻辑或耗时计算——因为日志、调试器甚至某些框架(如 Spring Boot Actuator)会在任意时机触发它,性能或稳定性容易出问题。
立即学习“Java免费学习笔记(深入)”;
实际场景中它悄悄被谁调用了?
除了显式调用 obj.toString(),这些地方都会隐式触发:
System.out.println(obj)String.valueOf(obj)- 字符串拼接:
"User: " + user - 日志框架(如 Log4j、SLF4J)打印对象参数时
- JUnit 断言失败时展示对象值(如
assertEquals(expected, actual))
基本上就这些。重写好 toString 是个低成本但高回报的习惯——花一分钟,换来的可能是排查 Bug 时少盯五分钟控制台。










