Java StringBuffer扩展后不更改引用

时间:2019-03-02 17:29:35

标签: java reference stringbuffer

来自StringBuffer docs

  

每个字符串缓冲区都有一个容量。只要字符串缓冲区中包含的字符序列的长度不超过容量,就不必分配新的内部缓冲区数组。如果内部缓冲区溢出,则会自动变大。

根据我的理解,这意味着如果我们对字符串缓冲区使用append方法,并且给定字符串的长度超过了字符串缓冲区的容量,JVM会自动为新的内存分配更大的内存字符串缓冲区,并将旧的字符串缓冲区与给定的字符串一起存储。但是,是这种情况,旧字符串缓冲区和新字符串缓冲区如何具有相同的引用,如下所示。附加的字符串大于16个字节,因此这将迫使JVM将一些新的内存分配给新的字符串缓冲区。

public class test {

    public static void main(String[] args) {

        StringBuffer sb = new StringBuffer("initial value");

        System.out.println("before: the reference is " + System.identityHashCode(sb));

        sb.append(" - this message is append through sb and this message is longer than 16 bytes");

        System.out.println("after: the reference is " + System.identityHashCode(sb));
    }
}

输出

before: the reference is 511833308
after: the reference is 511833308

2 个答案:

答案 0 :(得分:4)

通常情况下,存在一个间接层。实际字符数据存储在char[]对象中(通常)。相同的StringBuffer(或StringBuilder)实例将其对char[]的引用从旧对象更改为新对象。没有 new StringBuffer

java.lang.StringBuffer(和父类)的Java源代码可以随时使用。

答案 1 :(得分:0)

正如已经说过的,在附加字符串之后,StringBuffer引用没有改变,它仍然是相同的对象。它只是分配了更大的数组来存储字符。还值得一提的是,重写hashCode以返回有意义的字段的哈希值是一种好习惯,因为它可以帮助您跟踪对象的变异,但是由于StringBuffer不会覆盖它,并且由于您调用System.identityHashCode,它只会始终返回初始对象哈希,除非您将另一个StringBuffer实例分配给sb变量,否则它不会改变。最后一件事是,默认的hashCode实现不一定与对象引用相关,您不能依赖于此。