1.String
2.Stringbuffer
3.StringBuilder
4.三者之间的区别
5.使用策略
1.String
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[]; }
首先String是final类型,不能被继承的。
用于存放字符的数组被声明为final的,因此只能赋值一次,不可再更改。
2.Stringbuffer
/* @since JDK1.0
*/
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{ /**
* A cache of the last value returned by toString. Cleared
* whenever the StringBuffer is modified.
*/
private transient char[] toStringCache; @Override
public synchronized int length() {
return count;
} @Override
public synchronized int capacity() {
return value.length;
} @Override
public synchronized void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > value.length) {
expandCapacity(minimumCapacity);
}
} }
对于这个类很多方法都带有 synchronized 这个关键字。主要用于多线程环境
字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用StringBuffer,如果想转成String类型,可以调用StringBuffer的toString()方法。
这个类使用最多的方法是 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。append在末尾追加字符,insert在某个位置追加字符串
3.StringBuilder
* @since 1.5
*/
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{ /** use serialVersionUID for interoperability */
static final long serialVersionUID = 4383685877147921099L; /**
* Constructs a string builder with no characters in it and an
* initial capacity of 16 characters.
*/
public StringBuilder() {
super(16);
} /**
* Constructs a string builder with no characters in it and an
* initial capacity specified by the {@code capacity} argument.
*
* @param capacity the initial capacity.
* @throws NegativeArraySizeException if the {@code capacity}
* argument is less than {@code 0}.
*/
public StringBuilder(int capacity) {
super(capacity);
} }
StringBuilder:字符串变量(非线程安全)。在内部,StringBuilder对象被当作是一个包含字符序列的变长数组。
java.lang.StringBuilder是一个可变的字符序列,是JDK5.0新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。
其构造方法如下:
构造方法 | 描述 |
StringBuilder() | 创建一个容量为16的StringBuilder对象(16个空元素) |
StringBuilder(CharSequence cs) | 创建一个包含cs的StringBuilder对象,末尾附加16个空元素 |
StringBuilder(int initCapacity) | 创建一个容量为initCapacity的StringBuilder对象 |
StringBuilder(String s) | 创建一个包含s的StringBuilder对象,末尾附加16个空元素 |
在大部分情况下,StringBuilder > StringBuffer。这主要是由于前者不需要考虑线程安全。
4.三者之间的区别
String 类型和StringBuffer的主要性能区别:String是不可变的对象, 因此在每次对String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。
使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。所以多数情况下推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
但是一下情况列外:
String a="a"+"b"+"c";
StringBuffer sb=new StringBuffer();
sb.append("a").append("b").append("c");
第一种写法优于第二种写法,因为java编译把变量a直接设值为abc了
但是换成变量就需要第二种写法了。
5.使用策略
(1)基本原则:如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。
(2)不要使用String类的"+"来进行频繁的拼接,因为那样的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则。
(3)为了获得更好的性能,在构造 StirngBuffer 或 StirngBuilder 时应尽可能指定它们的容量。当然,如果你操作的字符串长度(length)不超过 16 个字符就不用了,当不指定容量(capacity)时默认构造一个容量为16的对象。不指定容量会显著降低性能。
(4)StringBuilder一般使用在方法内部来完成类似"+"功能,因为是线程不安全的,所以用完以后可以丢弃。StringBuffer主要用在全局变量中。
(5)相同情况下使用 StirngBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。而在现实的模块化编程中,负责某一模块的程序员不一定能清晰地判断该模块是否会放入多线程的环境中运行,因此:除非确定系统的瓶颈是在 StringBuffer 上,并且确定你的模块不会运行在多线程模式下,才可以采用StringBuilder;否则还是用StringBuffer。
(6)是使用StringBuilder还是StringBuffer的关键点是你的业务模块是否为多线程。