首页 > 代码库 > java基础巩固系列(十):String、StringBuffer、StringBuilder的使用与比较
java基础巩固系列(十):String、StringBuffer、StringBuilder的使用与比较
他们之间的主要区别:
String是字符串常量,不能够改变
StringBuffer是字符串变量,可以改变,线程安全
StringBuilder是字符串变量,可以改变,线程不安全(JDK1.5以后出现的)
一、为什么说String是字符串常量
public static void main(String[] args) { String s1 = "Hello "; String s2 = "World"; s1 += s2; System.out.println(s1); // Hello World s1 = s1.substring(6, 11); System.out.println(s1); //World }首先,我们让s1+=s2,然后s1的值变成了:Hello World
看起来是String对象s1的值改变了,但是实际上是s1被赋值了一个新的引用,这个引用指向“Hello World”这个字符串常量,而指向“Hello”的引用已经消失,这个时候“Hello”已经是属于过时的对象,会被GC回收。
然后,我们又使用了s1.substring(6,11)函数,这个函数也是返回了一个新的引用,这时指向“Hello World”的引用也已经消失了,s1是一个新的引用。
而且,对于String对象的操作(包括replaceAll、replace、substring)都是返回了一个新的string对象。
二、StringBuilder对象详解
API的解释:
线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
在需要对字符串执行重复修改的情况下,与创建新的 String 对象相关的系统开销可能会非常昂贵。
public static void main(String[] args) { StringBuffer s1 = new StringBuffer("abcdf"); s1.append("ghi"); //output:abcdfghi s1.insert(4, "e"); //output:abcdefghi }
三、String对象拼接操作符“+”的特殊情况
至此,我们已经知道String对象是一个不可变的常量,那么在String中进行 “+”拼接 操作的话,肯定也是要返回一个新的对象的,那么肯定会影响性能。
但是,有特殊的情况:
public static void main(String[] args) { //(1) String s1 = "Hello "; String s2 = "World!"; String s3 = s1 + s2; System.out.println(s3); //output:Hello World! //(2) String s = "Hello "+"World!"; //(3) StringBuffer sb = new StringBuffer("Hello "); sb.append("World!"); }在这三种情况中,按照速度排序:(2)>(3)>(1),这是JVM的一个特性,这时的String对象的拼接被解释成StringBuffer对象的拼接:
String s = "Hello "+"World!"; 被认为成 String s = "Hello World!";
四、String、StringBuffer、StringBuilder之间的区别
String是不可变的常量
StringBuffer与StringBuilder都是可以改变的变量,其中StringBuffer是线程安全的,保证同步;StringBuilder不是线程安全的,不能保证同步。
StringBuilder类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
java基础巩固系列(十):String、StringBuffer、StringBuilder的使用与比较