JDK1.8源码阅读之——String,StringBuffer, StringBuilder

来源:互联网 发布:iphone手机助手软件 编辑:程序博客网 时间:2024/06/06 01:45

    惭愧的说,工作快三年了。还没有读过jdk源码,随着工作时间越来越长,如果再不学点什么或许和刚毕业的实习生差不了多少了。为了跨出这个分水岭决定还是学点什么,那么就从面试经常问到的各种类之间的区别来看吧,先看常用的,其余的再补充。

一、String

首先是String类的定义,当用final修饰类的时候,此类不可被继承,即final类没有子类,并且对象是不可变的。
public final class String    implements java.io.Serializable, Comparable<String>, CharSequence{}
存储方式
** The value is used for character storage. */private final char value[];

二、StringBuffer

public final class StringBuffer    extends AbstractStringBuilder    implements java.io.Serializable, CharSequence{}
所有方法由synchronized修饰,线程安全
@Override    public synchronized int length() {        return count;    }    @Override    public synchronized int capacity() {        return value.length;    }
容量初始化
/**     * Constructs a string buffer with no characters in it and an     * initial capacity of 16 characters.     */    public StringBuffer() {        super(16);     //默认大小为16    }
再来看一下扩容
@Override    public synchronized StringBuffer append(Object obj) {        toStringCache = null;        super.append(String.valueOf(obj));        return this;    }
接着进入父类AbstractStringBuilder中
public AbstractStringBuilder append(String str) {        if (str == null)            return appendNull();        int len = str.length();        ensureCapacityInternal(count + len);        str.getChars(0, len, value, count);        count += len;        return this;}
private void ensureCapacityInternal(int minimumCapacity) {        // overflow-conscious code        if (minimumCapacity - value.length > 0)            expandCapacity(minimumCapacity);    }
由上面一段代码可以看出,如果添加的字符串长度大于当前数组长度长度会进行扩容
void expandCapacity(int minimumCapacity) {        int newCapacity = value.length * 2 + 2;        if (newCapacity - minimumCapacity < 0)            newCapacity = minimumCapacity;        if (newCapacity < 0) {            if (minimumCapacity < 0) // overflow                throw new OutOfMemoryError();            newCapacity = Integer.MAX_VALUE;        }        value = Arrays.copyOf(value, newCapacity);    }
扩容大小为 (原数组长度 * 2 + 2), 如果扩容后大小依旧比添加的字符串长度小,那么直接将添加的字符串长度作为容器大小, 如果新字符串长度溢出,最大长度为Integer最大值

三、StringBuilder

StringBuilder和StringButter同样继承AbstractStringBuilder。区别在于StringBuilder方法没有被sychronized修饰,因此不是线程安全的。

四、String,StringBuffer, StringBuilder 的区别是什么?String为什么是不可变的?

String是字符串常量,StringBufferStringBuilder是字符串变量。StringBuffer是线程安全的,StringBuilder是非线程安全的。具体来说String是一个不可变的对象,每次修改String对象实际上是创新新对象,并将引用指向新对象。效率很低。StringBuffer是可变的,即每次修改只是针对其本身,大部分情况下比String效率高,StringBuffer保证同步(synchronized),所以线程安全。StringBuilder没有实现同步,所以非线程安全。但效率应该比StringBuffer高。StringBuffer使用时最好指定容量,这样会比不指定容量快30%-40%,甚至比不指定容量的StringBuilder还快。




0 0