1. 先来说说String
看下JDK1.7 String成员变量的源码
- /**
- * @author Lee Boynton
- * @author Arthur van Hoff
- * @author Martin Buchholz
- * @author Ulf Zibis
- * @see java.lang.Object#toString()
- * @see java.lang.StringBuffer
- * @see java.lang.StringBuilder
- * @see java.nio.charset.Charset
- * @since JDK1.0
- */
- public final class String
- implements java.io.Serializable, Comparable<String>, CharSequence {
- /** The value is used for character storage. */
- private final char value[];
- /** Cache the hash code for the string */
- private int hash; // Default to 0
- /** use serialVersionUID from JDK 1.0.2 for interoperability */
- private static final long serialVersionUID = -6849794470754667710L;
可以看到String定义的成员变量value和hash,其中value是个字节数组,而且是final修饰,这个才是String不可变的关键点;
JDK1.7 String的部分注解
- The Java language provides special support for the string
- * concatenation operator ( + ), and for conversion of
- * other objects to strings. String concatenation is implemented
- * through the <code>StringBuilder</code>(or <code>StringBuffer</code>)
- * class and its <code>append</code> method.
- * String conversions are implemented through the method
- * <code>toString</code>, defined by <code>Object</code> and
- * inherited by all classes in Java. For additional information on
- * string concatenation and conversion, see Gosling, Joy, and Steele,
- * <i>The Java Language Specification</i>.
String提供修改内容的方法最终都是调用new String()。看下 String的部分注解
- /**
- * The <code>String</code> class represents character strings. All
- * string literals in Java programs, such as <code>"abc"</code>, are
- * implemented as instances of this class.
- * <p>
- * Strings are constant; their values cannot be changed after they
- * are created. String buffers support mutable strings.
- * Because String objects are immutable they can be shared. For example:
- * <p><blockquote><pre>
- * String str = "abc";
- * </pre></blockquote><p>
- * is equivalent to:
- * <p><blockquote><pre>
- * char data[] = {'a', 'b', 'c'};
- * String str = new String(data);
- * </pre></blockquote><p>
- * Here are some more examples of how strings can be used:
这里定义了一个String str = "abc";相当于char data[] = {'a', 'b', 'c'};String str = new String(data);
再来看一个substring()方法的源码
- /**
- * Returns a new string that is a substring of this string. The
- * substring begins at the specified <code>beginIndex</code> and
- * extends to the character at index <code>endIndex - 1</code>.
- * Thus the length of the substring is <code>endIndex-beginIndex</code>.
- * <p>
- * Examples:
- * <blockquote><pre>
- * "hamburger".substring(4, 8) returns "urge"
- * "smiles".substring(1, 5) returns "mile"
- * </pre></blockquote>
- *
- * @param beginIndex the beginning index, inclusive.
- * @param endIndex the ending index, exclusive.
- * @return the specified substring.
- * @exception IndexOutOfBoundsException if the
- * <code>beginIndex</code> is negative, or
- * <code>endIndex</code> is larger than the length of
- * this <code>String</code> object, or
- * <code>beginIndex</code> is larger than
- * <code>endIndex</code>.
- */
- public String substring(int beginIndex, int endIndex) {
- if (beginIndex < 0) {
- throw new StringIndexOutOfBoundsException(beginIndex);
- }
- if (endIndex > value.length) {
- throw new StringIndexOutOfBoundsException(endIndex);
- }
- int subLen = endIndex - beginIndex;
- if (subLen < 0) {
- throw new StringIndexOutOfBoundsException(subLen);
- }
- return ((beginIndex == 0) && (endIndex == value.length)) ? this
- : new String(value, beginIndex, subLen);
- }
看完这些,你可以清楚的知道定义一个变量str="hello world",则是在内存中分配一个对象new String("hello world"),当你修改str="hello nimei",变量重新指向内存中新分配的new String("hello nimei");原来内存中的new String("hello world")还在那里,没有改变,等待垃圾回收。难道真的没有办法修改new String("hello world")对象中的值而不重新在内存中重新new一次吗?让我们来看看一个例子。
原来通过反射可以修改String对象中的内容,反射太强大了。
2.StringBuffer和StringBuilder
StringBuffer的部分源码
- * @author Arthur van Hoff
- * @see java.lang.StringBuilder
- * @see java.lang.String
- * @since JDK1.0
- */
- public final class StringBuffer
- extends AbstractStringBuilder
- implements java.io.Serializable, CharSequence
- {
- /** use serialVersionUID from JDK 1.0.2 for interoperability */
- static final long serialVersionUID = 3388685877147921107L;
- /**
- * Constructs a string buffer with no characters in it and an
- * initial capacity of 16 characters.
- */
- public StringBuffer() {
- super(16);
- }
- /**
- * Constructs a string buffer with no characters in it and
- * the specified initial capacity.
- *
- * @param capacity the initial capacity.
- * @exception NegativeArraySizeException if the <code>capacity</code>
- * argument is less than <code>0</code>.
- */
- public StringBuffer(int capacity) {
- super(capacity);
- }
- /**
- * Constructs a string buffer initialized to the contents of the
- * specified string. The initial capacity of the string buffer is
- * <code>16</code> plus the length of the string argument.
- *
- * @param str the initial contents of the buffer.
- * @exception NullPointerException if <code>str</code> is <code>null</code>
- */
- public StringBuffer(String str) {
- super(str.length() + 16);
- append(str);
- }
StringBuilder的部分源码
- * @author Michael McCloskey
- * @see java.lang.StringBuffer
- * @see java.lang.String
- * @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</code> argument.
- *
- * @param capacity the initial capacity.
- * @throws NegativeArraySizeException if the <code>capacity</code>
- * argument is less than <code>0</code>.
- */
- public StringBuilder(int capacity) {
- super(capacity);
- }
- /**
- * Constructs a string builder initialized to the contents of the
- * specified string. The initial capacity of the string builder is
- * <code>16</code> plus the length of the string argument.
- *
- * @param str the initial contents of the buffer.
- * @throws NullPointerException if <code>str</code> is <code>null</code>
- */
- public StringBuilder(String str) {
- super(str.length() + 16);
- append(str);
- }
StringBuffer和StringBuilder的这部分源码基本一样,构造函数初始化大小都为16,都是继承了AbstractStringBuilder。
看看AbstractStringBuilder定义成员变量的源码
- /**
- * A mutable sequence of characters.
- * <p>
- * Implements a modifiable string. At any point in time it contains some
- * particular sequence of characters, but the length and content of the
- * sequence can be changed through certain method calls.
- *
- * @author Michael McCloskey
- * @author Martin Buchholz
- * @author Ulf Zibis
- * @since 1.5
- */
- abstract class AbstractStringBuilder implements Appendable, CharSequence {
- /**
- * The value is used for character storage.
- */
- char[] value;
- /**
- * The count is the number of characters used.
- */
- int count;
- /**
- * This no-arg constructor is necessary for serialization of subclasses.
- */
- AbstractStringBuilder() {
- }
- /**
- * Creates an AbstractStringBuilder of the specified capacity.
- */
- AbstractStringBuilder(int capacity) {
- value = new char[capacity];
- }
AbstractStringBuilder中定义的变量value,是个字节数组,和String的成员变量value相比,String的value是final修饰的,所以StringBuffer和StringBuilde的内容可以变。
在对比下StingBuffer和StringBuilder的实现其他细节,以append()方法为例。
- public synchronized StringBuffer append(String str) {
- super.append(str);
- return this;
- }
- public StringBuilder append(String str) {
- super.append(str);
- return this;
- }
2.String、StringBuffer和StringBuilder的总结
2). StringBuffer和StringBuilder相比,StringBuffer是synchronized的,是线程安全的,而StringBuilder是非线程安全的,单线程情况下性能更好一点;使用StringBuffer和StringBuilder时,可以适当考虑下初始化大小,较少扩容的次数,提高代码的高效性。

本文深入探讨了Java中String、StringBuffer和StringBuilder的区别与联系,详细解析了它们的内部实现原理及应用场景。
512

被折叠的 条评论
为什么被折叠?



