最近过来公司面试的人比较多,其中有一道笔试题就是问String、StringBuffer与StringBuilder之间区别 。发现虽然大家在程序中做字符串处理时经常用到,但对他们的真正区别好像不是太清楚,回答也千奇百怪!这里整理下它们三者之间的几点区别,以及使用场景,以供大家参考!
执行速度
1.执行速度方面三者有如下关系:
StringBuilder>StringBuffer>String;
分析原因
1.String执行速度慢于StringBuilder与StringBuffer原因:
- String 是字符常量;
- StringBuilder 是字符变量;
- StringBuffer 是字符变量;
从三者的源码定义不难发现,String是字符常量,也就是说是final类型的,是不可改变的,这里可能大家心里会有疑问了,先来看下下面的代码:
String ss = "dotest";
ss = ss + "addstr";
可能大家平时代码里经常这么写,问题来了,不是说String是字符常量吗?不是不能修改它的值吗?
其实是JVM的一种变相处理方式,可以看作是一种“欺骗”,对于上面两行代码JVM是这样处理的,先创建一个常量ss,并对它进行赋值dotest,然后当执行ss=ss+”addstr”时,JVM会临时再创建一个变量ss,并为它赋值dotest+addstr,之前的ss会通过垃圾回站GC进行回收进而释放内存。
而StringBuilder与StringBuffer则不同,它们是字符变量,对他们赋值,即是在同一个对象上进行操作,不存在GC回收,新对象创建等操作,现在可以理解为什么String为什么比StringBuilder与StringBuffer执行效率低了吧。
特殊的例子
String ss = "this is my"+"first"+"demo!";
StringBuffer buffer = new StringBuffer("this is my").append("first").append("demo!");
这个例子可以发现用ss生成很快,完全看不出用StringBuffer有什么效率方面的优势,其实了解下JVM对上面两句话的执行方式就会明白原因:
String ss = "this is my"+"first"+"demo!";
实际上JVM会以 String ss = “this is my first demo!”;来执行。
如果换下面的写法就能体现出速度差异了:
String ss = "this is my";
String dd = "first";
String ff = "demo!";
ss = ss + dd + ff;
这时JVM就会规规矩矩按上面分析到的方式进行处理。
StringBuffer与StringBuilder
StringBuffer 是线程安全的;
StringBuilder 是非线程一安全的;
当我们的字符缓冲区被多个线程使用时,JVM不能保证StringBuilder 操作是安全的,虽然速度是最快的,但是可以保证StringBuffer 的操作是安全的,不过大多情况下我们都是单线程在操作字符缓冲区,因此大多建议使用StringBuilder 的情况下就只是因为速度的原因。
总结
对于以上三者的使用情况简单总结如下:
- 如果少量的字符串操作采用String;
- 如果单线程下操作大量字符串采用StringBuilder ;
- 如果多线程下操作大量字符串采用StringBuffer ;