由于最近正好毕业了,正在找工作~~~参加了几场面试,发现好多公司都会问String,StringBuilder,StringBuffer三者之间的区别~~说实话,以前没了解过,所以不知道,其实网上很多都有相关的介绍,但是不理解为什么!所以今天就打算从源代码看看三者之间的区别~~~
首先看一下String的源码:
我们可以看出,String是一个final类型的一个类,不可以被继承。同时,String底层由char数组实现的~~~
我们先来看一下这个代码
String s1 =new String("abc")
以上会产生几个对象呢?
这是面试中经常出现的一个问题~~~
答案是:两个
为什么呢?我们来看一下源码:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
我们可以看你出来,String s1=new String("abc");其实就是将“abc”产生一个对象,并且把该对乡复制给s1对象~~~
这就是产生两个对象的原因!!!
同时呢,String产生之后的长度是不可改变的~~~那就有同学问了,s1+=s2是怎么回事?
其实,那是s1+s2产生一个新的String对象s1,原来的s1对象已经被废弃掉了~~~~
其实,这样效率非常的低的~~
而且在多线程的环境下是非同步的,也就是不安全的~~
这就是好多都推荐用StringBuffer或者StringBuilder的原因了~~~
我们看一下StringBuffer的源码:
StringBuffer继承于absractStringBuilder
创建方式有四种,其 中StringBuffer sb=new StringBuffer("qqqqq")的创建方式,是将String的长度+16产生一个新的StringBuffer对象,然后在调用apppend()方法将“qqqq”追加到StringBuffer对象中,那我们看一下append()的源码:
public synchronized StringBuffer append(String str) {
super.append(str);
return this;
}
public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
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);
}
append()方法内部直接就是调用父类的absractStringBuilder中的append(),在父类的append()中,首先判断追加后数组的长度是否超出现有长度,超出的话,就将
现有的数组产度扩充为:现有长度*2+2 ,然后在将内容复制到新数组中!!
可见,StringBuffer对象是可变的,长度可变不唯一,递增规则就是:现有长度*2+2
这样的话,效率上事要比String要高很多的~~~~
同时,StringBuffer的所用方法都是由synchronized关键字修饰,是线程安全的。
我们接下来看一下StringBuilder的源码:
是不是很熟悉阿?对!StringBuilder和StringBuffer在实现上基本一致,唯一一点区别就是StringBuilder是线程不安全的!!
这就是为什么两者的效率为什么基本一样的原因~~~~
OK,这样想必大家就对三者之间的关系有所理解了把~~~