前几天的一个面试官问到我String和StringBuffer的区别,当时我回答的不是很理想,这几天在网上看了一下大家的博客,自己也看了一下JDK中String,StringBuffer的内部实现,在这里记录一下。
关于String和StringBuffer的区别,我首先想到的是String创建对象是定长的,而StringBuffer创建的对象是可以动态改变长度的,当对字符串进行动态拼接时,StringBuffer的append()方法比String的+=效率高,那为什么String长度不可改变,而StringBuffer长度是可以改变的呢,这是为什么呢,我们可以看看String和StringBuffer的源码。
String类:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
/** The value is used for character storage. */
private final char value[];
public String() {
this.offset = 0;
this.count = 0;
this.value = new char[0];
}
}
可以看到,String类是被final修饰的,这就是说String类是最终类,不能被继承。String类包含一个私有的char类型的数组,同时这个数组被final修饰,意思是创建之后不能被修改,当调用String的默认构造方法,this.value = new char[]; char类型数组被创建,当然我们常用的都是都是有参的。由此可见,String对象的值是放在一个char[]里的,而这个char[]是被定义成final的。
StringBuffer类:
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
public StringBuffer() {
super(16);
}
}
AbstractStringBuilder类:
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
AbstractStringBuilder() {
}
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
StringBuffer继承了AbstractStringBuilder类,而在AbstractStringBuilder类里可以清楚的看到,定义了一个char[] ,注意额,这个数组没有被定义成final,StringBuffer的默认构造方法调用父类的构造方法,默认长度是16。当我们调用append()方法时,如果然来的空间不足,那么AbstractStringBuilder最终会调用Arrays这个类,重新创建一个字符数组,然后将原来那个数组copy到这个新的数组中。而实现copy功能是System类的arrayCopy方法,这是一个本地方法。
Array类的copyOf()方法:
public static char[] copyOf(char[] original, int newLength) {
char[] copy = new char[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
System类的arraycopy()方法:
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
至此,分析完毕,然来写博客这么累。