不可变String及可变StringBuilder

 String和StringBuilder、StringBuffer的小总结


一、不可变String

先查看JDK文档看下String

 
  
public final class String
extends Object
implements Serializable, Comparable, CharSequence

String是final类型,意味着它是不可改变的,然而每次对String的操作看起来貌似是把它改变了,,,其实是每次都重新创建了一个全新的String对象,去包含修改后的字符串,而最初的String是丝毫没有动的。

public class StringTest {

	public static String upcase(String str){
		return str.toUpperCase();
	}
	public static void main(String[] args) {
		String a =  "abcd";
		System.out.println("-1-a-->"+a);
		String aaa = upcase(a);
		System.out.println("--aaa->"+aaa);
		System.out.println("-2--1>"+a);
		
	}
}
结果为:

-1-a-->abcd
--aaa->ABCD
-2--1>abcd
可以看到第一次的a和第二次的a的值是没有变化的。

当字符串a当做参数传递的时候,实际传递的只是引用的一个拷贝,而实际该引用所指的对象一直待在单一的物理位置上。

你可以为一个String指定任意多的别名,但是任何引用都不能改变它的值,因为String对象具有只读性。

二、String的重载操作符“+”

String的不可变会带来一定的效率问题,“+”和“+=”是String对象在Java中仅有的两个重载的操作符,重载就意味着操作符在应用于特定的类时,被赋予了特殊的意义。(在C++中允许程序员任意重载操作符)。

public class StringTest {

	public static void main(String[] args) {

		String str1 = "helloworld";
		String str2 = "ab"+"bc"+"cd"+12345+str1;
		System.out.println(str2);
	}
}
结果

abbccd12345helloworld
可以看到上面用到了很多“+”重载操作符,我们可能会想,这不是会产生一大堆需要垃圾回收的中间对象吗,其实不是这样。

,这样就谈到了字符串的另一个表现形式,StringBuilder

三、线程安全StringBuffer,非线程安全StringBuilder

接着上面的例子说,,在使用“+”的时候,系统其实不是重新创建好多的String来得出最后结果的,它默认使用了StringBuilder对象的append()方法,StringBuilder的append()方法效率更好。

然而我们又想了,,String的重载“+”是不是可以随便用了呢,,,答案是否定的。

当在一个循环体中使用“+”,,最后toString()的时候,,每次循环系统都会默认创建一个StringBuilder对象来进行append()操作。这样是不是就没有我们自己在循环体外定义一个StringBuilder在循环体内使用append()来的更好呢。。嘿嘿。。


那么StringBuilder和StringBuffer又有什么关系呢

StringBuilder是Java5.0之后引入的,之前使用的都是StringBuffer,后者是线程安全的,因此开销会更大些。本人开始对线程安全不是很理解,还需继续探讨线程的有关内容了。,,,目前大概理解为,线程安全,或保证线程的同步需要加synchronized方法,,我们在单线程中,或者是不必考虑线程同步的问题时,请优先选择StringBuilder类。。。。

























你可能感兴趣的:(ThinkingInJava)