今日我在阅读阿里巴巴开发手册泰山版,发现开发手册上有这么一条:【推荐】 循环体内,字符串的连接方式,使用 StringBuilder 的 append 方法进行扩展。
字符串的三种表示类型
String类型
String是不可变类型。 下面是jdk11里面String类的源码,String的成员变量有value和hash。value是一个引用,指向String封装的数组对象。value是被private final修饰的,并且没有提供setvalue等用于修改值的公共方法。所以String是不可变的。
每次对String的操作,一旦修改String对象,都会生成新的String对象。下面是String类中的replace()函数,每次修改String函数会调用,并return new String(buf, true);。因此在循环体中,使用String进行连接不仅效率低下,而且造成内存资源浪费。
StringBuffer类型
StringBuffer类是线程安全的可变数据类型,继承于 AbstractStringBuilder类。
下面是jdk11里面StringBuffer类的源码。StringBuffer类具体实现了可变字符序列的操作比如append()、insert()、delete()、replace()、charAt()等。这些方法都被sychronized修饰,是线程安全的。
StringBuffer是线程安全的可变数据类型。StringBuffer类的对象能够被多次的修改,并且不产生新的未使用对象。对于不要求线程安全或者单线程的情况下,StringBuffer因为线程加锁导致性能损耗,所以在循环体中,使用StringBuffe效率低。
StringBuilder类型
StringBuilder是线程不安全的可变数据类型。与StringBuffer类一样,继承于 AbstractStringBuilder类。
下面是jdk11里面StringBuffer类的源码。StringBuffer类具体实现了可变字符序列的操作比如append()、insert()、delete()、replace()、charAt()等。与StringBuffer不同,这些方法没有加锁,不能降低性能,所以手册中建议使用StringBuilder。
String、StringBuilder和StringBuffer的性能测试
测试代码如下:
执行结果如下:随着循环次数的增长,在循环体中StringBuilder的性能优势越来越明显。
网友评论