String,StringBuilder,StringBuffer这三个类在Java都能用来操作字符串,但是在性能与线程安全上稍有差异,需要根据使用的业务场景加以注意。以下为差异的详述:
一、String:
1.查看源码发现String类拥有的成员变量value为final,因此一旦创建就无法改变其对象。
每次操作String字符串时都是会创建一个新的对象。
1 public final class String 2 implements java.io.Serializable, Comparable<String>, CharSequence { 3 /** The value is used for character storage. */ 4 private final char value[]; //value 是一个数组,且是final的,不可修改 5 6 /** Cache the hash code for the string */ 7 private int hash; // Default to 0 8 9 }
二、StringBuilder & StringBuffer:
1.查看源码发现StringBuilder & StringBuffer对字符串操作,不会创建新的对象,只是修改成员变量value对象
的值。因此操作字符串 StringBuilder & StringBuffer 会比 String 性能高。
1 /* 1 */ 2 public final class StringBuilder 3 extends AbstractStringBuilder 4 implements java.io.Serializable, CharSequence{ 5 /*累计字符串的方法 不会创建行的对象,直接修改value对象*/ 6 @Override 7 public StringBuilder append(String str) { 8 super.append(str); 9 return this; 10 } 11 } 12 13 /* 2 */ 14 abstract class AbstractStringBuilder implements Appendable, CharSequence { 15 16 /*value 引用一个数组 */ 17 char[] value; 18 19 int count; 20 21 /*累加字符串的方法 */ 22 @Override 23 public AbstractStringBuilder append(CharSequence s, int start, int end) { 24 if (s == null) 25 s = "null"; 26 if ((start < 0) || (start > end) || (end > s.length())) 27 throw new IndexOutOfBoundsException( 28 "start " + start + ", end " + end + ", s.length() " 29 + s.length()); 30 int len = end - start; 31 ensureCapacityInternal(count + len); 32 for (int i = start, j = count; i < end; i++, j++) 33 value[j] = s.charAt(i); 34 count += len; 35 return this; 36 } 37 38 /*修改 value*/ 39 private void ensureCapacityInternal(int minimumCapacity) { 40 // overflow-conscious code 41 if (minimumCapacity - value.length > 0) { 42 value = Arrays.copyOf(value, 43 newCapacity(minimumCapacity)); 44 } 45 } 46 47 }
2.StringBuilder & StringBuffer 的提供的方法基本一致,但是通过查看源码发现StringBuffer提供的方法都是线程安全的。
1 public final class StringBuffer 2 extends AbstractStringBuilder 3 implements java.io.Serializable, CharSequence 4 { ... 5 @Override 6 public synchronized StringBuffer append(Object obj) { 7 toStringCache = null; 8 super.append(String.valueOf(obj)); 9 return this; 10 } 11 }
三、总结:
1.String:适用于少量操作字符串的情况
2.StringBuilder:适用于单线程下大量操作字符串的情况
3.StringBuffer:适用于多线程下大量操作字符串的情况