You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何修改StringBuilder会改变其哈希码?打印的标识哈希值为何不同?

解答你的两个StringBuilder相关疑问

疑问一:为何修改StringBuilder会改变它的哈希码?

首先要纠正一个关键认知:StringBuilder本身并没有重写Object类的hashCode()方法,它使用的是父类Object的默认实现。

Object的hashCode()(以及System.identityHashCode())返回的是对象的标识哈希值,这个值是基于对象在JVM中的唯一内存标识生成的,和对象的内容完全无关。也就是说,只要你操作的是同一个StringBuilder实例,哪怕你修改它的内容(append、insert等),它的哈希码都不会改变。

比如你可以跑这段代码验证:

StringBuilder sb = new StringBuilder("hello");
int initialHash = sb.hashCode();
sb.append(" everyone");
int modifiedHash = sb.hashCode();
System.out.println(initialHash == modifiedHash); // 输出true,因为是同一个实例

你之所以可能觉得修改内容会改变哈希码,大概率是混淆了String和StringBuilder的特性:String是不可变类,每次修改都会生成新的String实例,所以新实例的哈希码自然不同;但StringBuilder是可变类,所有修改操作都是在原实例上进行的,不会生成新对象,因此哈希码保持不变。

疑问二:为什么每次打印的标识哈希值都不一样?

看你的printBuilder方法里的这行代码:

StringBuilder build = new StringBuilder(dataBuild);

这行代码的作用是创建一个全新的StringBuilder实例,把传入的dataBuild的内容复制到这个新实例中。也就是说,每次调用printBuilder,你都会生成一个完全独立的StringBuilder对象。

而System.identityHashCode()的作用是返回每个对象实例的唯一标识哈希值——不同的对象实例,哪怕内容完全一样,这个值也几乎不可能重复。所以你每次打印的"address"(实际是标识哈希值)不一样,本质原因就是每次都在打印一个新创建的StringBuilder对象的标识哈希。

如果想打印原对象的标识哈希,你只需要去掉创建新实例的代码,直接使用传入的dataBuild即可:

private static void printBuilder(StringBuilder dataBuild){
    System.out.println("data = " + dataBuild);
    System.out.println("length = " + dataBuild.length());
    System.out.println("capacity = " + dataBuild.capacity());
    int addressBuild = System.identityHashCode(dataBuild);
    System.out.println("address = " + Integer.toHexString(addressBuild));
}

这样修改后,三次打印的标识哈希值就会完全相同,因为你一直操作的是同一个StringBuilder实例。

另外提一句,你提供的输出里length和capacity的值看起来像是写反了(比如初始"hello"的length应该是5,capacity默认是16),可能是输出时的笔误,不过这不影响核心问题的解答。

内容的提问来源于stack exchange,提问作者rio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:42:55