阿里面试实战题3----String,StringBuilder,StringBuffer区别
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[]; 5 }
可以特别明显的看出。String是final类型,不可被继承。同时底层的数据结构--数组,也是final不可变的。
StringBuilder
1 public final class StringBuilder 2 extends AbstractStringBuilder 3 implements java.io.Serializable, CharSequence 4 { 5 public StringBuilder() { 6 super(16); 7 } 8 9 } 10 11 abstract class AbstractStringBuilder implements Appendable, CharSequence { 12 13 char[] value; 14 15 AbstractStringBuilder(int capacity) { 16 value = new char[capacity]; 17 } 18 }
同样可以看出,StringBuilder不同于String,char数组是非final类型,可被修改。
StringBuffer
他是安全版的StringBuilder,他所有方法都加了synchronized。
例子如下:
1 public class Main { 2 public static void main(String[] args) { 3 String s1 = "aaa"; 4 String s2 = s1.concat("bbb"); 5 System.out.println(s2.equals(s1)); 6 } 7 } 8 9 public String concat(String str) { 10 int otherLen = str.length(); 11 if (otherLen == 0) { 12 return this; 13 } 14 int len = value.length; 15 char buf[] = Arrays.copyOf(value, len + otherLen); 16 str.getChars(buf, len); 17 return new String(buf, true); 18 }
其实我们可以看到,在contact方法的第17行。他其实是return了一个新的String类型,而不是旧的String类型。
所以s1和s2肯定不会是相同的。
1 public class Main { 2 public static void main(String[] args) { 3 StringBuilder s1 = new StringBuilder("aaa"); 4 StringBuilder s2 = s1.append("bbb"); 5 System.out.println(s2.equals(s1)); 6 } 7 } 8 9 public AbstractStringBuilder append(String str) { 10 if (str == null) 11 return appendNull(); 12 int len = str.length(); 13 ensureCapacityInternal(count + len); 14 str.getChars(0, len, value, count); 15 count += len; 16 return this; 17 }
可以看到,在append的16行,他返回的是return this。也就是当前对象的内存,也就是当前内存发生了变化。
所以s1和s2也就相等了。
适用场景
如果频繁的要修改字符串的内容的话,那么就使用StringBuilder。
否则建议使用String。
因为String的不可变,使得其非常的“安全”。包括在HashSet,HashMap中使用,都十分的“安全”。
可以参考这篇回答:String和StringBuffer以及StringBuilder的性能差异 ?