String、StringBuffer、StringBuilder有什么区别
很多人都用过String、StringBuffer、StringBuilder
,但是很多人都是只其然,不知其所以然,这三个都是我们平常经常用到的字符串。
那么它们到底有什么区别呢?
一般的回答都是这样:
String
是Java中最基础的类,也是最重要的类,几乎每天都在和它打交到,而它提供了管理和构造字符串的各种逻辑,它是典型的Immutable
类,并且被声明成了final,我们知道一个类被声明成类final,那么它所有的属性也是final。由于它的不可变性、类似的拼接、裁剪字符串等动作、都会产生新的String对象,由于操作字符串是普遍性,往往操作的效率对性能都有明显的影响。
StringBuffer
是解决String 拼接 产生太多新的对象,而提供的一个类,我们经常用到它的append和add方法,把字符串添加到已有序列的末尾或者指定的位置,StringBuffer本质是一个线程安全,可修改的字符序列,它保证了线程安全,但是往往线程安全,那么性能就会大大折扣,如果不考虑安全,那么可以选择后者StringaBuilder。
StringBuilder是jdk 1.5
中增加的,它和StringBuffer唯一的区别就是线程不是安全的。但是性能比StringBuffer好。
底层实现细节
String
是Immutable类的典型实现,原生的保证了基础线程安全,因为你无法对它内部数据进行任何修改,这种便利甚至体现在拷贝构造函数中,由于不可变,Immutable对象在拷贝时不需要额外复制数据。
看StringBufer
实现的一些细节,它的线程安全是通过把各种修改数据的方法都加上synchronized
关键字实现的,非常直白。其实,这种简单粗暴的实现方式,非常适
合我们常见的线程安全类实现,不必纠结于synchronized性能之类的
为了实现修改字符序列的目的,StringBufer和StringBuilder底层都是利用可修改
的(char,JDK 9以后是byte)数组,二者都继承了AbstractStringBuilder
,里面包含了基本
操作,区别仅在于最终的方法是否加了synchronized。
另外构建时初始字符串长度加16,如果没有构建对象时输入最初的字符串,那么初始值就是16
过Java的字符串,在历史版本
中,它是使用char数组来存数据的,这样非常直接。但是Java中的char是两个bytes大小,拉丁语系语言的字符,根本就不需要太宽
的char,这样无区别的实现就造成了一定的浪费