- StringBuffer & StringBuilde
- 七StringBuilder,StringBuffer
- StringBuilder、StringBuffer、Strin
- String、StringBuffer、StringBuilde
- String、StringBuffer、StringBuilde
- String、Stringbuffer、StringBuilde
- String、StringBuffer、StringBuilde
- String,StringBuffer,StringBuilde
- String、StringBuffer、StringBuilde
- String、StringBuffer、StringBuilde
![](https://img.haomeiwen.com/i10764455/df9a7ca65c8098e7.png)
String 是不可变量。用final关键字修饰字符数组来保存字符串。
![](https://img.haomeiwen.com/i10764455/e6d2904b92e2e0a9.png)
StringBuffer 和 StringBuilder都继承自AbstractStringBuilder 类,在 AbstractStringBuilder 中也是使用字符数组保存字符串char[]value 但是没有用 final 关键字修饰,所以这两种对象都是可变的。
![](https://img.haomeiwen.com/i10764455/c9caf237156cabf1.png)
线程安全性
String中的对象是不可变的,即常量,所以线程安全。
StringBuffer对方法或者继承的方法加了同步锁(synchronized),所以线程安全。
StringBuilder没有添加同步锁,所以不是线程安全。
性能
每次对String类型进行改变时,都会生成一个新的String对象,然后将指针指向新的String对象。
StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
最佳实践
操作少量的数据: 适用String
单线程操作字符串缓冲区下操作大量数据: 适用StringBuilder
多线程操作字符串缓冲区下操作大量数据: 适用StringBuffer
字符串常量实例
public static void main(String[] args) {
// 字符串常量,分配在常量池中,编译器会对其进行优化, Interned table
// 即当一个字符串已经存在时,不再重复创建一个相同的对象,而是直接将s2也指向"hello".
String s1 = "hello";
String s2 = "hello";
// new出来的对象,分配在heap中.s3与s4虽然它们指向的字符串内容是相同的,但是是两个不同的对象.
// 因此==进行比较时,其所存的引用是不同的,故不会相等
//这句话创建了两个对象,一个"hello"在编译时创建在常量池中,一个在运行时创建在堆中
String s3 = new String("hello");
String s4 = new String("hello");
System.out.println(s1 == s2); // true
System.out.println(s3 == s4); // false
System.out.println(s3.equals(s4)); // true
System.out.println(s1 == s3); //false
System.out.println(s3.equals(s1)); //true
// String中equals方法已经被重写过,比较的是内容是否相等.
}
网友评论