String、StringBuffer、StringBuidler 知识整理

String、StringBuffer、StringBuidler、这三个家伙,大家都不陌生,肯定也都会用。三者异同大家都能说出来,但是其根本原因是什么呢?带着下面问题,学习一下。

第一、String与后两者不同,为什么String对象不可变,后两者对象可变呢?

第二、线程安全方面,为什么StringBuffer比StringBuidler安全呢?

1.我们首先看String的源码(截取一小部分):

 1 public final class String
 2     implements java.io.Serializable, Comparable<String>, CharSequence {
 3     /** The value is used for character storage. */
我标红的地方就是关键,String中的字符串是通过数组char来存储的,而它的修饰符是final,这就解释了为什么String对象不可变的原因。
4 private final char value[]; 5 6 /** Cache the hash code for the string */ 7 private int hash; // Default to 0

2.看看StringBuilder源码

它继承了AbstractStringBuilder这个类。

1     @Override
2     public StringBuilder append(CharSequence s) {
3         super.append(s);
4         return this;
5     }

在append()方法里,会调用父类AbstractStringBuilderappend()的方法。

 父类append方法如下                 代码2

1
// Documentation in subclasses because of synchro difference 2 @Override 3 public AbstractStringBuilder append(CharSequence s) { 4 if (s == null) 5 return appendNull(); 6 if (s instanceof String) 7 return this.append((String)s); 8 if (s instanceof AbstractStringBuilder) 9 return this.append((AbstractStringBuilder)s); 10 11 return this.append(s, 0, s.length()); 12 }
 1     @Override                  代码3(标识用)
 2     public AbstractStringBuilder append(CharSequence s, int start, int end) {
 3         if (s == null)
 4             s = "null";
 5         if ((start < 0) || (start > end) || (end > s.length()))
 6             throw new IndexOutOfBoundsException(
 7                 "start " + start + ", end " + end + ", s.length() "
 8                 + s.length());
 9         int len = end - start;
10         ensureCapacityInternal(count + len);
11         for (int i = start, j = count; i < end; i++, j++)
12             value[j] = s.charAt(i);
13         count += len;
14         return this;
15     }

上述代码3中的12行value在源码中定义是 char[] value;  没有final关键字。

3.说说StringBuffer

它也是继承了AbstractStringBuilder这个类,

1     @Override
2     public synchronized StringBuffer append(CharSequence s) {
3         toStringCache = null;
4         super.append(s);
5         return this;
6     }

在append方法中,加入了synchronized关键字,所以在多想城称重,StringBuffer是安全的,但是安全的代价就是影响了一些速度,因此速度肯定慢于StringBuilder。这里也就解释文章开头提出的第二个问题。

简单的整理记录一下。不对的地方欢迎指正。

原文地址:https://www.cnblogs.com/lihao007/p/7857383.html