而且通过StringBuilder和StringBuffer继承自同一个父类这点, 我们可以推断出它俩的方法都是差不多的. 通过查看源码也发现确实如此, 只不过StringBuffer在方法上添加了 synchronized关键字, 证明它的方法绝大多数方法都是线程同步方法. 也就是说在多线程的环境下我们应该使用StringBuffer以保证线程安全, 在单线程环境下我们应使用StringBuilder以获得更高的效率。
既然如此, 我们的比较也就落到了StringBuilder和String身上了。
关于StringBuilder和String之间的讨论通过查看StringBuilder和String的源码我们会发现两者之间一个关键的区别: 对于String, 凡是涉及到返回参数类型为String类型的方法, 在返回的时候都会通过new关键字创建一个新的字符串对象; 而对于StringBuilder, 大多数方法都会返回StringBuilder对象自身。
就因为这点区别, 使得两者在操作字符串时在不同的场景下会体现出不同的效率。
下面还是以拼接字符串为例比较一下两者的性能:
就拼接5万次字符串而言, StringBuilder的效率是String类的956倍。
我们再次通过反编译代码看看造成两者性能差距的原因, 先看String类. (为了方便阅读代码, 我删除了计时部分的代码, 并重新编译, 得到的main方法反编译代码如下)
从反汇编代码中可以看到, 当用String类拼接字符串时, 每次都会生成一个StringBuilder对象, 然后调用两次append()方法把字符串拼接好, 最后通过StringBuilder的toString()方法new出一个新的字符串对象。
也就是说每次拼接都会new出两个对象, 并进行两次方法调用, 如果拼接的次数过多, 创建对象所带来的时延会降低系统效率, 同时会造成巨大的内存浪费. 而且当内存不够用时, 虚拟机会进行垃圾回收, 这也是一项相当耗时的操作, 会大大降低系统性能。
下面是使用StringBuilder拼接字符串得到的反编译代码: