JDK源码分析之String、StringBuilder和StringBuffer
什么是String、StringBuilder和StringBuffer
- String是Java中的一个不可变字符序列,使用final char[] value来存储数据,也就是说,一旦被初始化,就不能再对其进行修改。
- StringBuilder和StringBuffer实现的是可变的字符序列,都是在原有的值基础上进行修改,区别在于StringBuilder是非线程安全的,而StringBuffer是线程安全的。
String、StringBuilder和StringBuffer的区别
- String是不可变的,每次修改都会产生新的对象,效率相对较低,但在多线程的情况下是线程安全的。
- StringBuilder是可变的,每次修改都是在原有的对象中进行修改,效率相对较高,但在多线程的情况下是不安全的。
- StringBuffer是可变的,每次修改都是在原有的对象中进行修改,效率也不如StringBuilder高,但在多线程的情况下是线程安全的。
String、StringBuilder和StringBuffer的使用场景
- 当字符串内容不会改变时,使用String;
- 当字符串内容经常会发生改变时,并且不是在多线程环境下,使用StringBuilder;
- 当字符串内容经常会发生改变时,并且是在多线程环境下,使用StringBuffer。
String、StringBuilder和StringBuffer的源码实现分析
String的源码实现
- String底层实现是一个char数组,使用final修饰,也就是说,一旦被初始化,就不能再对其进行修改;
- String在创建过程中会常量池中查找是否有相同值的字符串,如果有就直接返回该字符串的引用,否则才会创建新的字符串。
示例1:String的使用
String str = "hello world";
System.out.println(str);//输出hello world
- 上面的代码中,字符串"hello world"以常量的形式存储在常量池中,当我们定义一个字符串变量str时,只是将该字符串的地址赋值给str,而并不是重新创建一个字符串。
StringBuilder的源码实现
- StringBuilder底层实现也是一个char数组,但并没有使用final修饰,因此可以进行修改;
- 在进行字符串拼接等操作时,会根据当前的容量和最小需要的容量来判断是否需要扩容,扩容的大小为原来的2倍+2;
- StringBuilder没有线程安全的实现。
示例2:StringBuilder的使用
StringBuilder builder = new StringBuilder();
builder.append("Hello");
builder.append(" World");
System.out.println(builder.toString());//输出Hello World
- 上面的代码中,我们通过append方法进行字符串拼接,最终输出Hello World。
StringBuffer的源码实现
- StringBuffer底层实现也是一个char数组,但是所有的方法都使用了synchronized关键字进行同步,因此是线程安全的;
- 在进行字符串拼接等操作时,会根据当前的容量和最小需要的容量来判断是否需要扩容,扩容的大小为原来的2倍+2。
总结
- String、StringBuilder和StringBuffer都是用来存储字符串的类,它们之间有很多的区别,根据不同的场景选择合适的类使用是十分重要的;
- 源码实现中,需要注意String的不可变性,而StringBuilder和StringBuffer的扩容机制。
参考资料:
- 《深入理解Java虚拟机》
- 《Effective Java》
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JDK源码分析之String、StringBuilder和StringBuffer - Python技术站