String对象是不变的{:3_46:}!可以变化的是String对象的引用。
String name = "ray";
name.concat("long"); //字符串连接
System.out.println(name); //输出name,ok,还是"ray"
name = name.concat("long"); //把字符串对象连接的结果赋给了name引用
System.out.println(name); //输出name,oh!,变成了"raylong"
上述三条语句其实产生了3个String对象,"ray","long","raylong"。第2条语句确实产生了"raylong"字符串,但是没有指定把该字符串的引用赋给谁,因此没有改变name引用。第3条语句根据不变性,并没有改变"ray",JVM创建了一个新的对象,把"ray","long"的连接赋给了name引用,因此引用变了,但是原对象没变。
StringBuffer类。StringBuffer类是可变的,不会在字符串常量池中,而是在堆中,不会留下一大堆无用的对象。而且它可将字符串缓冲区安全地用于多个线程。每个StringBuffer对象都有一定的容量。只要StringBuffer对象所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。这个固定的容量是16个字符这种算法起个名字叫“添饭算法”
(开玩笑的{:3_67:})。先给你一满碗饭,不够了再给你一满碗饭。
例子:
StringBuffer sb = new StringBuffer(); //初始容量为 16 个字符
sb.append("1234"); //这是4个字符,那么16个字符的容量就足够了,没有溢出
System.out.println(sb.length()); //输出字符串长度是4
System.out.println(sb.capacity()); //输出该字符串缓冲区的容量是16
sb.append("12345678901234567"); //这是17个字符,16个字符的容量不够了,扩容为17+16个字符的容量
System.out.println(sb.length()); //输出字符串长度是17
System.out.println(sb.capacity()); //输出该字符串缓冲区的容量是34
sb.append("890").reverse().insert(10,"-");
System.out.println(sb); //输出0987654321-09876543214321
|