每个字符串缓冲区都有一个容量。只要字符串缓冲区中包含的字符序列的长度不超过容量,就不必分配新的内部缓冲区数组。如果内部缓冲区溢出,则会自动变大。
根据我的理解,这意味着如果我们对字符串缓冲区使用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
答案 0 :(得分:4)
通常情况下,存在一个间接层。实际字符数据存储在char[]
对象中(通常)。相同的StringBuffer
(或StringBuilder
)实例将其对char[]
的引用从旧对象更改为新对象。没有 new StringBuffer
。
java.lang.StringBuffer
(和父类)的Java源代码可以随时使用。
答案 1 :(得分:0)
正如已经说过的,在附加字符串之后,StringBuffer
引用没有改变,它仍然是相同的对象。它只是分配了更大的数组来存储字符。还值得一提的是,重写hashCode
以返回有意义的字段的哈希值是一种好习惯,因为它可以帮助您跟踪对象的变异,但是由于StringBuffer
不会覆盖它,并且由于您调用System.identityHashCode
,它只会始终返回初始对象哈希,除非您将另一个StringBuffer
实例分配给sb
变量,否则它不会改变。最后一件事是,默认的hashCode
实现不一定与对象引用相关,您不能依赖于此。