String
String类 在 Java 中被声明为final,所有的属性也都是final的。因此对于String的裁剪拼接等,都必须是要生成新的字符串。因此对于String的操作,效率比较低下。
StringBuffer
StringBuffer是线程安全的,它的线程安全是通过把各种修改数据的方法都加上 synchronized 关键字来实现的。StringBuffer的出现是为了克服String的这种效率低下的弊端,在它的底层使用了可修改的char数组注意1。在新建一个StringBuffer 对象时,默认创建的数组大小是16加上字符串的长度。因为如果数组过大会对空间造成浪费,数组过小,在我们进行具体的操作的时候,比如拼接等,空间又会不够。当空间不够的时候还需要对此扩容,扩容时又需要对原数组进行复制,会再次对性能造成影响。因此我们如果已经明确知道此StringBuffer会发生拼接,并且大概可以预计其最终拼接后的大小,就可以在new StringBuffer的时候对其大小进行指定,以防止不必要的开销。
StringBuilder
StringBuilder的设计基本和StringBuffer是相同的,不同的是StringBuilder不是线程安全的,它的修改数据的方法没有加关键字 synchronized,效率会比StringBuffer更高。因此,如果是在单线程运行的情况下(一般都是此种场景),优先选择StringBuilder。StringBuffer 和 StringBuilder 都继承了 AbstractStringBuilder类。
注意
- 在JDK9以后已经换成了byte数组,因为Java中的 char 是两个 bytes 大小,拉丁语系语言的字符不需要太宽的 char,会对空间造成浪费。