Object类toString()默认输出“类全限定名@哈希码十六进制”,三部分组成:类全限定名标识创建类,@为硬编码分隔符,哈希码是identityHashCode快照,不随字段变化,设计目标是集合分桶而非业务展示。

Java 中 Object 类的 toString() 方法在未重写时输出形如 com.example.User@1a2b3c4d 的字符串,这不是“对象名”,而是三部分组成的底层标识:类全限定名 + @ 符号 + 哈希码十六进制表示。它不体现业务数据,只反映 JVM 层面对该实例的基本识别信息。
类全限定名说明“谁创建了这个实例”
比如 com.example.User 表示该对象由这个包路径下的 User 类构造而来。它和对象当前字段值无关——两个 id 都是 1001、name 都是“李四”的 User 实例,只要属于同一个类加载器下的同一类,这里就完全一样;但如果一个来自 com.example.User,另一个来自 org.test.User,哪怕代码一模一样,显示的类名也不同。
@ 符号只是硬编码的分隔符
它没有语义,不是运算符,也不参与逻辑判断。Java 源码里直接写死为 "@",作用仅是视觉上把类名和后面那串数字分开,类似用短横线或冒号做分隔,可读性上毫无帮助,纯属格式约定。
十六进制哈希码是 identityHashCode 的快照
这部分(如 1a2b3c4d)本质是 hashCode() 返回的 int 值,经 Integer.toHexString() 转换而来。关键点包括:
立即学习“Java免费学习笔记(深入)”;
- 它通常与对象首次创建时的 JVM 内部标识有关,但不等于内存地址(现代 HotSpot 已随机化)
- 不会随字段修改而变化——改了
name或age,只要没重写hashCode(),这串十六进制就不变 - 不是唯一 ID,哈希冲突常见,不同对象可能算出相同值
- 设计目标是配合
equals()在HashMap等集合中快速分桶,不是供人阅读的标识
为什么默认输出这么“无用”?
因为 Object.toString() 是兜底机制:当开发者没提供业务视角的描述时,至少能区分“这是不是同一个类的不同实例”。日志里看到 User@7f56a1c2,你只能确认它是个 User 实例,但无法知道它的 id 是多少、是否已激活、邮箱是什么——这也正是几乎所有实体类、DTO、VO 都必须重写 toString() 的根本原因。


















