String、StringBuffer和StringBuilde
String、StringBuffer和StringBuilder的区别和原理
这三个类的主要区别在两个方面:运算速度(运算性能或执行效率)和线程安全性。
1,运算速度比较
一般情况下,运算速度相比较:
StringBuilder > StringBuffer > String
String是final类不能被继承且为字符串常量,而StringBuilder和StringBuffer均为字符串变量。
String对象一旦创建就不能被更改,而后面两个是可以修改的,StringBuilder和StringBuffer只能通过构造函数进行创建对象,对象创建之后,会在内存中分配内存空间,并初始化保存一个null,通过append方法向StringBuffer和StringBuilder中赋值。请看代码:
String str = "abc";
str = str + "de";
上面两行代码,第一行代码是先创建一个字符串对象
str
,然后把“abc”
赋值给str
,运行到第二行的时候,JVM会创建一个新的str
对象,并将str+"de"
的值赋值给新的str
对象。而第一个被创建的str
对象被JVM的垃圾回收机制(GC)回收掉。所以str
对象并没有被更改,String类型对象一旦被创建就不能被改变。所以Java中对String对象进行的操作实际上是一个不断创建并回收对象的过程,因此在运行速度上很慢。
而StringBuilder和StringBuffer的对象是变量,对变量的操作是直接对该对象就行更改,因此不会进行反复的创建和回收。所以在运行速度上比较快。
注意:但是有一种特殊情况,如果是两个已知的字符串进行相加,就很快。看下面代码:
String str = "abc" + "de";
StringBuilder stringBuilder = new StringBuilder().append("abc").append("de");
System.out.println(stringBuilder.toString());
上述代码中String的操作速度反而要比StringBuilder快,这是因为在JVM眼里,第1行的代码操作和下列代码是完全一样的,所以很快。
但如下的代码写法形式速度会很慢,JVM会不断地创建和回收对象来进行操作。
String str1 = "abc";
String str2 = "de";
String str = str1 + str2;
2,线程安全性
StringBuilder : 线程不安全
因为StringBuilder的方法没有
synchronized
关键字修饰,所以不能保证线程安全性。是JDK1.5
新增的,该类提供一个与StringBuffer兼容的 API,但不能保证同步,所以在性能上较高。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
StringBuffer : 线程安全
StringBuffer中大部分方法由synchronized关键字修饰,在必要时可对方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致,所以是线程安全的。类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
3,总结
String : 适用于少量的字符串操作
StringBuilder :适用于单线程下在字符串缓冲区进行大量操作。
StringBuffer :适用于多线程下在字符串缓冲区进行大量操作。
4,小结
本篇文章简单介绍了String、StringBuffer和StringBuilder的区别和原理,由于纯手打,难免会有纰漏,如果发现错误的地方,请第一时间告诉我,这将是我进步的一个很重要的环节。