String、StringBuffer、StringBuilder的区别千万不要死记硬背了

String、StringBuffer和StringBuilder它们三者的区别,是面试官们最爱问的问题之一,它们之间到底有什么区别呢?

1.值可变性

String 是字符串常量,字符串长度不可变。

查看源码可以发现,String类是被 final 修饰的,String内部的 value 也是被 final 修饰的。因此,每次修改String的值时,如果该值在常量池中不存在时,都会在常量池中产生一个新的字符串,并重新指向这个新的字符串。

StringBuffer和StringBuilder都是可变类,它们在字符串变更的时候不会产生新的对象。

2.线程安全
String是不可变类,因此它是线程安全的。 StringBuffer是线程安全的,因为它的每个方法都加了 synchronized 关键字。

StringBuilder不是线程安全的。

3.性能

在String的类注释上写得很清楚,String是一个常量,在其创建之后就不能被改变。

String在拼接字符串和修改字符串的时候,每次都需要在常量池中创建和重新分配内存,丢弃原来的字符串,最后将指针指向新字符串,因此它的性能是最低的。

StringBuffer具有可变性,可以直接修改字符串,因此它的性能要比String高。但StringBuffer加了同步锁,是堵塞的,对性能有一定影响。StringBuilder也具有可变性,也可以直接修改字符串,并且无堵塞。因此,StringBuilder的性能在这三者之中是最高的。

4.数据存储

网上经常会有这么一道面试题,String s = new String("abc"); 创建了几个对象?
首先看常量池中有没有字符串"abc",没有就分配空间创建一个字符串"abc"。
对象都是在堆上创建的,String对象创建后,就把常量池中的"abc"拷贝到堆内存空间中。
s是引用变量,指向新创建的对象。
我们使用最频繁的是 String s = "abc";引用变量s直接指向常量池中的字符串"abc",因此它是存储在常量池中。

StringBuffer和StringBuilder存储在堆内存空间,都继承自AbstractStringBuilder类,创建对象不指定容量时,默认容量为16。

最后总结
如果操作少量的字符串,建议使用String;如果在单线程中操作大量的字符串,建议使用StringBuilder;如果在多线程中操作大量的字符串,涉及到线程安全,那么就使用StringBuffer。千万不要再使用String对象进行+++了,最费性能。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。