Object默认toString()输出的是对象身份快照而非业务摘要:类全限定名标识创建者,@为固定分隔符,十六进制哈希码是identityHashCode的十六进制表示,不随字段变化且非唯一,仅用于集合分桶。

它代表的是对象的“身份快照”,不是内容摘要,也不具备业务含义。
类全限定名:说明“谁造的它”
比如 com.example.User,这部分只告诉你这个实例属于哪个类——包括包路径和类名。它不反映对象当前状态,哪怕两个 User 对象字段一模一样,只要它们来自不同类加载器或不同包下的同名类,这里显示的类名就可能不同。
@ 符号:纯分隔作用,无任何语义
这个字符是 Java 源码里写死的,就像写 “User-12345” 中的短横线,只是为了把类名和后面那串数字区分开,本身没有任何逻辑功能或额外信息。
十六进制哈希码:基于 identity 的整数快照
这部分(如 1a2b3c4d)是 hashCode() 返回值转成十六进制后的字符串,关键点有:
- 它通常与对象创建时的 JVM 内部标识有关,但不等于内存地址,现代 HotSpot 已加入随机化,避免暴露真实布局
- 它不会随字段修改而变化——改了 name 或 id,只要没重写 hashCode(),这串十六进制就不动
- 它不是唯一 ID,哈希冲突常见,不同对象可能算出相同值
- 它的设计目标是配合
equals()在 HashMap 等集合中快速分桶,而非供人阅读
为什么默认输出这么“难懂”?
因为 Object 的 toString() 是兜底机制:当开发者没提供业务视角的描述时,至少能区分“是不是同一个类的不同实例”。你在日志里看到 User@7f56a1c2,只能确认这是一个 User 类的实例,完全看不出它的 id 是多少、姓名叫什么——这正是必须重写 toString() 的根本原因。

















