转自:http://coderdream.iteye.com/blog/845822
String 与StringBuffer区别详解
1. 概念
1.1、 String 与 StringBuffer 的区别
String :在String 类中没有用来改变已有字符串中的某个字符的方法,由于不能改变一个Java 字符串中的某个单独字符,所以在JDK 文档中称String 类的对象是不可改变 的。
但是,不可改变的字符串具有一个很大的优点:编译器可以把字符串设为共享的。如果新建一个对象指向已有相同内容的String 对象,这会直接指向已有的对象(共享对象),而不会新建String 对象。
StringBuffer :StringBuffer 类属于一种辅助类,可预先分配指定长度的内存块建立一个字符串缓冲区。这样使用StringBuffer 类的append 方法追加字符。例如String 使用(+ )操作符添加字符到一个已经存在的字符串后面有效率得多。因为使用(+ )操作符每一次将字符添加到一个字符串中去时,字符串对象都需要寻找一个新的内存空间来容纳更大的字符串,这无凝是一个非常消耗时间的操作。添加多个字符也就意味着要一次又一次的对字符串 重新分配内存。使用StringBuffer 类就避免了这个问题。
1.2、 示例 1
代码清单1 :StringAndStringBuffer .java 片段
public static void stringReplace(String text) {
text = text.replace( 'j' , 'i' );
System. out .println( "text in stringReplace: " + text);
}
public static void bufferReplace(StringBuffer text) {
text = text.append( "C" );
System. out .println( "text in bufferReplace: " + text);
}
@Test
public void test1() {
String textString = new String( "java" );
StringBuffer textBuffer = new StringBuffer( "java" );
stringReplace (textString);
bufferReplace (textBuffer);
System. out .println(textString + textBuffer);
}
输出结果:
text in stringReplace: iava
text in bufferReplace: javaC
javajavaC
1.3、 解析
String 示例
1) 先创建了一个名textString 的String 类型的对象引用;
2) 创建一个内容为java 的String 对象(我们假定为对象a );
3) 将textString 引用指向对象a ;
4) 执行stringReplace 方法时,将textString 的地址copy 给text ,text 也指向了textString 的对象a ;
5) text.replace('j', 'i'); 的结果是生成新的String 类型对象b , 内容为"iava" ;
6) 这里要注意,String 对象时final 类型的,内容是不可以改变的,所以会新建一个String 类型的对象b ;
7) 所以,text = text.replace('j', 'i'); 就会重新使text 指向对象b ;
8) 由于该方法的返回类型是void, 所以原来的textString 没变。
StringBuffer 示例
1) 先创建了一个名textBuffer 的StringBuffer 类型的对象引用;
2) 创建一个内容为java 的StringBuffer 对象(我们假定为对象a );
3) 将textBuffer 引用指向对象a ;
4) 执行bufferReplace 方法时,把textBuffer 的地址copy 给text ;
5) 然后沿着text 指向的字符串( 其实也就是textBuffer 指向的对象) 操作,添加一个"C" ;
6) 虽然没有任何返回,但是这个操作影响到了textBuffer 所指向的字符串;
7) 所以这里打印"javaC" 。
1.4、 示例 2
代码清单2 :StringAndStringBuffer .java 片段
@Test
public void test2() {
// 生成一个新的引用对象,指向 String 对象 "java"
String textString = new String( "java" );
System. out .println( "HashCode: " + textString.hashCode() + "\tValue:"
+ textString);
// 引用对象指向新的 String 对象 "ja"
textString = textString.substring(0, 2);
// 前后指向不同的引用,所以 HashCode 不同
System. out .println( "HashCode: " + textString.hashCode() + "\tValue:"
+ textString);
// 生成一个新的引用对象,指向 StringBuffer 对象 "java"
StringBuffer textBuffer = new StringBuffer( "java" );
System. out .println( "HashCode: " + textBuffer.hashCode() + "\tValue:"
+ textBuffer);
// 直接操作 StringBuffer 对象,在后面加字符串 "abc"
textBuffer.append( "abc" );
// 前后引用指向不变,所以 HashCode 相同
System. out .println( "HashCode: " + textBuffer.hashCode() + "\tValue:"
+ textBuffer);
}
输出结果:
HashCode: 3254818 Value:java
HashCode: 3383 Value:ja
HashCode: 17682935 Value:java
HashCode: 17682935 Value:javaabc