谬误15 相差甚远——String与StringBuffer基本上相同
String类和StringBuffer类都用来处理字符串,它们之间有着较多相似的常规用法,并且这二者之间可以相互转换,这导致许多人在程序设计中不严格区分这两者,甚至认为这两者基本相同,是可以通用的。实际上,这两者之间的内在差别非常大,下面将对这两个类的区分进行详细的说明。
说明
String类型表示Unicode字符的字符串,该类型的字符串对象是只读的,也就是说,一旦创建了某个字符串对象,那么该字符串对象就不能够被修改。
String类型创建的字符串是无法修改的,表面看起来能够修改字符串的所有方法实际上并没有修改原有的字符串,而是生成了另外一个全新的字符串对象。
示例代码如下:
public class Test { //利用String类修改字符串 private static void UseString (){ String str = "你好"; //创建字符串对象 String str2 = str + ",明日科技"; //修改字符串 if(str. equals (str2)){ //若两个字符串的引用相同 System.out. println ("原有字符串对象被修改"); }else{ System.out. println ("原有字符串对象没有被修改,而是生成新的字符串对象"); } } public static void main (String[] args){ UseString(); //调用UseString方法 } }
说明
在上面代码的UseString方法中,首先创建了一个字符串对象,然后在该字符串对象上利用“+”号修改字符串,接着使用equals方法比较修改前和修改后的两个字符串是否具有相同的引用。
上述代码运行后,在控制台输出的信息如图4.11所示。
图4.11 利用String类型修改字符串输出的信息
从上面的运行结果可以看到,字符串对象在利用“+”拼接后,生成了另外一个新的字符串对象。
StringBuilder类型表示值为可变字符序列的类似字符串的对象,之所以说值是可变的,是因为可以对StringBuilder 对象进行追加、移除、替换或插入字符来对其进行修改,这点与String类型恰恰相反。
大多数修改StringBuilder 实例的方法都返回对同一实例的引用,由于返回的是对实例的引用,因此可以调用该引用的方法或属性。如果想要编写将连续操作依次连接起来的单个语句,这将会很方便,代码如下:
public class Test { //利用StringBuffer类修改字符串 private static void UserStringBuffer (){ StringBuffer str = new StringBuffer ("你好"); //创建字符串对象 StringBuffer str2 = str. append (",明日科技"); //修改字符串 if(str. equals (str2)){ //若两个字符串的引用相同 System.out. println ("原有字符串对象被修改"); }else{ System.out. println ("原有字符串对象没有被修改,而是生成新的字符串对象"); } } public static void main (String[] args){ UserStringBuffer (); //调用UseStringBuffer方法 } }
说明
在上面代码的UseStringBuffer方法中,首先使用指定字符串“你好”创建StringBuffer类型的实例,然后将字符串“,明日科技”通过append ()方法添加到字符串中,接着使用equals方法比较修改前和修改后的两个实例是否具有相同的引用。
上述代码运行后,在控制台输出的信息如图4.12所示。
图4.12 利用StringBuffer类型修改字符串输出的信息
从上面的分析可以看出,String类型和StringBuffer类型完全不相同,String类型的字符串是只读的、不可修改的,而StringBuffer类型的字符串是动态可修改的字符串。