String、StringBuffer、StringBuilder

422 阅读2分钟

String

String是典型的Immutable类,被声明为final class,属性也是final。所以类似拼接、裁剪字符串等工作,都会产生新的String对象。

StringBuffer

StringBuffer解决了String拼接产生的太多中间对象的问题。我们可以通过append或者add方法,将字符串添加到已有的序列的末尾或者指定位置。并且StringBuffer是一个线程安全的类,它的所有修改方法被synchronized关键字修饰。

StringBuilder

StringBuffer随时线程安全的,但也带来了额外的性能开销,除非有线程安全的需求。StringBuilder就是去掉了线程安全部分的StringBuffer。

扩展

String因为是典型的Immutable实现,所以它原生的保证了线程的安全性。

字符串是Java中非常常用的对象,所以JVM对字符串做了很多优化。

Java6以后,JVM会把类似"abc"这样的文本字符串缓存起来,但被缓存的字符串存在PermGen(永久代)里,通过intern方法从缓存中取字符串而不是重新创建,这空间有限,也基本不会被FullGC之外的垃圾回收照顾到,所以使用不当会OOM。

Oracle JDK 8u20之后,也就是G1 GC下的字符串重排序,将相同数据的字符串指向同一份数据。

Java9中还引入了Compact Strings的设计,将数据存储由原来的char数组,改变成byte数组。这样使字符串更紧凑。使用更小的内存占用、更快的操作速度。

String,StringBuffer,StringBuilder的选择上,不必太过于纠结性能。 “过早优化是万恶之源”,考虑可靠性、正确性和代码可读性才是大多数应用开发最重要的因素。