Java深入学习22:String StringBuffer Stirngbuilder
String
字符串常量,字符串长度不可变。Java 中 String 是 immutable(不可变)的。
用于存放字符的数组被声明为 final 的,因此只能赋值一次,不可再更改。
/** The value is used for character storage. */ private final char value[]; /** The offset is the first index of the storage that is used. */ private final int offset; /** The count is the number of characters in the String. */ private final int count;
StringBuffer(JDK1.0)
字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。
// A thread-safe, mutable sequence of characters. public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ char[] value; public StringBuffer() { super(16); } public StringBuffer(int capacity) { super(capacity); } @Override public synchronized int length() { return count; } @Override public synchronized StringBuffer append(Object obj) { toStringCache = null; super.append(String.valueOf(obj)); return this; } } abstract class AbstractStringBuilder implements Appendable, CharSequence { char[] value; AbstractStringBuilder(int capacity) { value = new char[capacity]; } }
StringBuilder(JDK5.0)
字符串变量(非线程安全)。在内部,StringBuilder 对象被当作是一个包含字符序列的变长数组。
//A mutable sequence of characters. This class provides an API compatible with {@code StringBuffer}, but with no guarantee of synchronization. public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ public StringBuilder() { super(16); } public StringBuilder(int capacity) { super(capacity); } }
三者区别
String 类型和 StringBuffer 的主要性能区别:String 是不可变的对象, 因此在每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。
使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。所以多数情况下推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
在某些特别情况下(没有循环情况), String 对象的字符串拼接其实是被 Java Compiler 编译成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,即单行用加号拼接字符串是没有性能损失的。但在有循环的情况下,编译器没法做到足够智能的替换,仍然会有不必要的性能损耗,因此,用循环拼接字符串的时候,还是老老实实的用stringbuilder吧。
使用策略
(1)基本原则:如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。
(2)不要使用String类的"+"来进行频繁的拼接,因为那样的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则
END
String字符串常量,字符串长度不可变。Java 中 String 是 immutable(不可变)的。用于存放字符的数组被声明为 final 的,因此只能赋值一次,不可再更改。/** The value is used for character storage. */private final char value[];
/** The offset is the first index of the storage that is used. */private final int offset;
/** The count is the number of characters in the String. */private final int count;
StringBuffer(JDK1.0)字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。 // A thread-safe, mutable sequence of characters. public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ char[] value; public StringBuffer() { super(16); } public StringBuffer(int capacity) { super(capacity); }
@Override public synchronized int length() { return count; } @Override public synchronized StringBuffer append(Object obj) { toStringCache = null; super.append(String.valueOf(obj)); return this; }}
abstract class AbstractStringBuilder implements Appendable, CharSequence { char[] value; AbstractStringBuilder(int capacity) { value = new char[capacity]; }}
StringBuilder(JDK5.0)字符串变量(非线程安全)。在内部,StringBuilder 对象被当作是一个包含字符序列的变长数组。//A mutable sequence of characters. This class provides an API compatible with {@code StringBuffer}, but with no guarantee of synchronization.public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ public StringBuilder() { super(16); } public StringBuilder(int capacity) { super(capacity); }}
三者区别String 类型和 StringBuffer 的主要性能区别:String 是不可变的对象, 因此在每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。所以多数情况下推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。在某些特别情况下(没有循环情况), String 对象的字符串拼接其实是被 Java Compiler 编译成了 StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,即单行用加号拼接字符串是没有性能损失的。但在有循环的情况下,编译器没法做到足够智能的替换,仍然会有不必要的性能损耗,因此,用循环拼接字符串的时候,还是老老实实的用stringbuilder吧。
使用策略(1)基本原则:如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。(2)不要使用String类的"+"来进行频繁的拼接,因为那样的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则