String、StringBuffer和StringBuilder它们三者的区别,是面试官们最爱问的问题之一,它们之间到底有什么区别呢?
1.值可变性
String 是字符串常量,字符串长度不可变。
查看源码可以发现,String类是被 final 修饰的,String内部的 value 也是被 final 修饰的。因此,每次修改String的值时,如果该值在常量池中不存在时,都会在常量池中产生一个新的字符串,并重新指向这个新的字符串。StringBuffer和StringBuilder都是可变类,它们在字符串变更的时候不会产生新的对象。
2.线程安全
String是不可变类,因此它是线程安全的。 StringBuffer是线程安全的,因为它的每个方法都加了 synchronized 关键字。
3.性能
在String的类注释上写得很清楚,String是一个常量,在其创建之后就不能被改变。
String在拼接字符串和修改字符串的时候,每次都需要在常量池中创建和重新分配内存,丢弃原来的字符串,最后将指针指向新字符串,因此它的性能是最低的。StringBuffer具有可变性,可以直接修改字符串,因此它的性能要比String高。但StringBuffer加了同步锁,是堵塞的,对性能有一定影响。StringBuilder也具有可变性,也可以直接修改字符串,并且无堵塞。因此,StringBuilder的性能在这三者之中是最高的。
4.数据存储
网上经常会有这么一道面试题,String s = new String("abc"); 创建了几个对象?
首先看常量池中有没有字符串"abc",没有就分配空间创建一个字符串"abc"。
对象都是在堆上创建的,String对象创建后,就把常量池中的"abc"拷贝到堆内存空间中。
s是引用变量,指向新创建的对象。
我们使用最频繁的是 String s = "abc";引用变量s直接指向常量池中的字符串"abc",因此它是存储在常量池中。
最后总结
如果操作少量的字符串,建议使用String;如果在单线程中操作大量的字符串,建议使用StringBuilder;如果在多线程中操作大量的字符串,涉及到线程安全,那么就使用StringBuffer。千万不要再使用String对象进行+++了,最费性能。
网友评论