首先推荐一篇来自大神的博客http://blog.csdn.net/chengyingzhilian/article/details/7781858
- String类型
String类型是长度不可变的字符串类型。参看String的定义源码:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { /** The value is used for character storage. */ private final char value[]; ...... } 可以看出String底层存储的方式是字符数组。声明为final类型,长度不可变。那么会有一个问题
输出结果为:abc123.String str1 = "abc"; str1 = str1+"123"; System.out.println(str1);
这个字符串的长度不是变了吗?这是一个可变的吗?? 其实这俩行代码的执行过程是这样的:首先创建对象str1,赋予一个"abc",然后再创建一个新的对象str1 ,用来执行第二行代码,也就是说我们之前对象str1并没有变化,所以我们说String类型是不可改变的对象了,由于这种机制,每当用String操作字符串时,实际上是在不断的创建新的对象,而原来的对象就会变为垃圾被GC回收掉,可想而知这样执行效率会有多底。
String类型支持共享,可以说String是线程安全的。
2.StringBuffer类型和StringBuilder类型
StringBuffer与StringBuilder都是字符串变量,他们的长度是可变的。每当我们用它们对字符串做操作时,实际上是在一个对象上操作的,这样就不会像String一样创建一些而外的对象进行操作了,当然速度就快了。
public class StringBufferTest { public static void main(String [] args) { StringBuffer str1 = new StringBuffer("hello"); System.out.println(str1.hashCode());//366712642 str1 = str1.append(" world"); System.out.println(str1.hashCode());//366712642 String str2 = "hello"; System.out.println(str2.hashCode());//99162322 str2 = str2 + "world"; System.out.println(str2.hashCode());//-1524582912 } }
可以简单的看一下StringBuffer的源码:
可以看到他的成员方法全部添加同步了,所以StringBuffer是线程安全的。public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence { //存储空间 private transient char[] toStringCache; static final long serialVersionUID = 3388685877147921107L; //构造方法,默认为16个字符的容量 public StringBuffer() { super(16); } public StringBuffer(int capacity) { super(capacity); } public StringBuffer(String str) { super(str.length() + 16); append(str); } public StringBuffer(CharSequence seq) { this(seq.length() + 16); append(seq); } @Override public synchronized int length() { return count; } @Override public synchronized int capacity() { return value.length; } @Override public synchronized void ensureCapacity(int minimumCapacity) { if (minimumCapacity > value.length) { expandCapacity(minimumCapacity); } } .......其他的成员方法 }
StringBuilder是线程不安全的,但是它的执行效率却是最高的。通常情况下我们选择StringBuilder更能提高执行效率。
对于三者使用的总结: 1.如果要操作少量的数据用 = String
2.单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
3.多线程操作字符串缓冲区 下操作大量数据 = StringBuffer