String和StringBuilder、StringBuffer的区别

String和StringBuilder、StringBuffer的区别



(原文地址:http://blog.csdn.net/dfdsggdgg/article/details/51347748


一、String


看下JDK1.7 String成员变量的源码

[java]  view plain  copy
  1. /** 
  2.  * @author  Lee Boynton 
  3.  * @author  Arthur van Hoff 
  4.  * @author  Martin Buchholz 
  5.  * @author  Ulf Zibis 
  6.  * @see     java.lang.Object#toString() 
  7.  * @see     java.lang.StringBuffer 
  8.  * @see     java.lang.StringBuilder 
  9.  * @see     java.nio.charset.Charset 
  10.  * @since   JDK1.0 
  11.  */  
  12.   
  13. public final class String  
  14.     implements java.io.Serializable, Comparable<String>, CharSequence {  
  15.     /** The value is used for character storage. */  
  16.     private final char value[];  
  17.   
  18.     /** Cache the hash code for the string */  
  19.     private int hash; // Default to 0  
  20.   
  21.     /** use serialVersionUID from JDK 1.0.2 for interoperability */  
  22.     private static final long serialVersionUID = -6849794470754667710L;  

可以看到String定义的成员变量value和hash,其中value是个字节数组,而且是final修饰,这个才是String不可变的关键点;

JDK1.7 String的部分注解

[java]  view plain  copy
  1. The Java language provides special support for the string 

  2. * concatenation operator ( + ), and for conversion of  
  3. * other objects to strings. String concatenation is implemented  
  4. * through the <code>StringBuilder</code>(or <code>StringBuffer</code>)  
  5. class and its <code>append</code> method.  
  6. * String conversions are implemented through the method  
  7. * <code>toString</code>, defined by <code>Object</code> and  
  8. * inherited by all classes in Java. For additional information on  
  9. * string concatenation and conversion, see Gosling, Joy, and Steele,  
  10. * <i>The Java Language Specification</i>.  

上面解释了:

java为String提供了特殊的支持,例如:String a="a";  String b="b" ;当执行String c=a+b操作时,实际上是创建一个StringBuilder对象或者StringBuffer对象,再通过apend()进行拼接,最后调用toStirng()生成一个新的对象给c


String提供修改内容的方法最终都是调用new String()。看下 String的部分注释

[java]  view plain  copy
  1. /**  
  2.  * The <code>String</code> class represents character strings. All  
  3.  * string literals in Java programs, such as <code>"abc"</code>, are  
  4.  * implemented as instances of this class.  
  5.  * <p>  
  6.  * Strings are constant; their values cannot be changed after they  
  7.  * are created. String buffers support mutable strings.  
  8.  * Because String objects are immutable they can be shared. For example:  
  9.  * <p><blockquote><pre>  
  10.  *     String str = "abc" 
  11.  * </pre></blockquote><p>  
  12.  * is equivalent to:  
  13.  * <p><blockquote><pre>  
  14.  *     char data[] = {'a''b''c'};  
  15.  *     String str = new String(data);  
  16.  * </pre></blockquote><p>  
  17.  * 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()方法的源码

[java]  view plain  copy
  1. /** 
  2.      * Returns a new string that is a substring of this string. The 
  3.      * substring begins at the specified <code>beginIndex</code> and 
  4.      * extends to the character at index <code>endIndex - 1</code>. 
  5.      * Thus the length of the substring is <code>endIndex-beginIndex</code>. 
  6.      * <p> 
  7.      * Examples: 
  8.      * <blockquote><pre> 
  9.      * "hamburger".substring(4, 8) returns "urge" 
  10.      * "smiles".substring(1, 5) returns "mile" 
  11.      * </pre></blockquote> 
  12.      * 
  13.      * @param      beginIndex   the beginning index, inclusive. 
  14.      * @param      endIndex     the ending index, exclusive. 
  15.      * @return     the specified substring. 
  16.      * @exception  IndexOutOfBoundsException  if the 
  17.      *             <code>beginIndex</code> is negative, or 
  18.      *             <code>endIndex</code> is larger than the length of 
  19.      *             this <code>String</code> object, or 
  20.      *             <code>beginIndex</code> is larger than 
  21.      *             <code>endIndex</code>. 
  22.      */  
  23.     public String substring(int beginIndex, int endIndex) {  
  24.         if (beginIndex < 0) {  
  25.             throw new StringIndexOutOfBoundsException(beginIndex);  
  26.         }  
  27.         if (endIndex > value.length) {  
  28.             throw new StringIndexOutOfBoundsException(endIndex);  
  29.         }  
  30.         int subLen = endIndex - beginIndex;  
  31.         if (subLen < 0) {  
  32.             throw new StringIndexOutOfBoundsException(subLen);  
  33.         }  
  34.         return ((beginIndex == 0) && (endIndex == value.length)) ? this  
  35.                 : new String(value, beginIndex, subLen);  
  36.     }  


看完这些,你可以清楚的知道定义一个变量str="hello world",则是在内存中分配一个对象new String("hello world"),当你修改str="hello nimei",变量重新指向内存中新分配的new String("hello nimei");原来内存中的new String("hello world")还在那里,没有改变,等待垃圾回收。、


难道真的没有办法修改new String("hello world")对象中的值而不重新在内存中重新new一次吗?让我们来看看一个例子。


原来通过反射可以修改String对象中的内容,反射太强大了。



二、StringBuffer和StringBuilder


StringBuffer的部分源码

[java]  view plain  copy
  1. @author      Arthur van Hoff  
  2.  * @see     java.lang.StringBuilder  
  3.  * @see     java.lang.String  
  4.  * @since   JDK1.0  
  5.  */  
  6.  public final class StringBuffer  
  7.     extends AbstractStringBuilder  
  8.     implements java.io.Serializable, CharSequence  
  9. {  
  10.   
  11.     /** use serialVersionUID from JDK 1.0.2 for interoperability */  
  12.     static final long serialVersionUID = 3388685877147921107L;  
  13.   
  14.     /** 
  15.      * Constructs a string buffer with no characters in it and an 
  16.      * initial capacity of 16 characters. 
  17.      */  
  18.     public StringBuffer() {  
  19.         super(16);  
  20.     }  
  21.   
  22.     /** 
  23.      * Constructs a string buffer with no characters in it and 
  24.      * the specified initial capacity. 
  25.      * 
  26.      * @param      capacity  the initial capacity. 
  27.      * @exception  NegativeArraySizeException  if the <code>capacity</code> 
  28.      *               argument is less than <code>0</code>. 
  29.      */  
  30.     public StringBuffer(int capacity) {  
  31.         super(capacity);  
  32.     }  
  33.   
  34.     /** 
  35.      * Constructs a string buffer initialized to the contents of the 
  36.      * specified string. The initial capacity of the string buffer is 
  37.      * <code>16</code> plus the length of the string argument. 
  38.      * 
  39.      * @param   str   the initial contents of the buffer. 
  40.      * @exception NullPointerException if <code>str</code> is <code>null</code> 
  41.      */  
  42.     public StringBuffer(String str) {  
  43.         super(str.length() + 16);  
  44.         append(str);  
  45.     }  


StringBuilder的部分源码

[java]  view plain  copy
  1. @author      Michael McCloskey  
  2.  * @see         java.lang.StringBuffer  
  3.  * @see         java.lang.String  
  4.  * @since       1.5  
  5.  */  
  6. public final class StringBuilder  
  7.     extends AbstractStringBuilder  
  8.     implements java.io.Serializable, CharSequence  
  9. {  
  10.   
  11.     /** use serialVersionUID for interoperability */  
  12.     static final long serialVersionUID = 4383685877147921099L;  
  13.   
  14.     /** 
  15.      * Constructs a string builder with no characters in it and an 
  16.      * initial capacity of 16 characters. 
  17.      */  
  18.     public StringBuilder() {  
  19.         super(16);  
  20.     }  
  21.   
  22.     /** 
  23.      * Constructs a string builder with no characters in it and an 
  24.      * initial capacity specified by the <code>capacity</code> argument. 
  25.      * 
  26.      * @param      capacity  the initial capacity. 
  27.      * @throws     NegativeArraySizeException  if the <code>capacity</code> 
  28.      *               argument is less than <code>0</code>. 
  29.      */  
  30.     public StringBuilder(int capacity) {  
  31.         super(capacity);  
  32.     }  
  33.   
  34.     /** 
  35.      * Constructs a string builder initialized to the contents of the 
  36.      * specified string. The initial capacity of the string builder is 
  37.      * <code>16</code> plus the length of the string argument. 
  38.      * 
  39.      * @param   str   the initial contents of the buffer. 
  40.      * @throws    NullPointerException if <code>str</code> is <code>null</code> 
  41.      */  
  42.     public StringBuilder(String str) {  
  43.         super(str.length() + 16);  
  44.         append(str);  
  45.     }  


StringBuffer和StringBuilder的这部分源码基本一样,构造函数初始化大小都为16,都是继承了AbstractStringBuilder


看看AbstractStringBuilder定义成员变量的源码

[java]  view plain  copy
  1. /** 
  2.  * A mutable sequence of characters. 
  3.  * <p> 
  4.  * Implements a modifiable string. At any point in time it contains some 
  5.  * particular sequence of characters, but the length and content of the 
  6.  * sequence can be changed through certain method calls. 
  7.  * 
  8.  * @author      Michael McCloskey 
  9.  * @author      Martin Buchholz 
  10.  * @author      Ulf Zibis 
  11.  * @since       1.5 
  12.  */  
  13. abstract class AbstractStringBuilder implements Appendable, CharSequence {  
  14.     /** 
  15.      * The value is used for character storage. 
  16.      */  
  17.     char[] value;  
  18.   
  19.     /** 
  20.      * The count is the number of characters used. 
  21.      */  
  22.     int count;  
  23.   
  24.     /** 
  25.      * This no-arg constructor is necessary for serialization of subclasses. 
  26.      */  
  27.     AbstractStringBuilder() {  
  28.     }  
  29.   
  30.     /** 
  31.      * Creates an AbstractStringBuilder of the specified capacity. 
  32.      */  
  33.     AbstractStringBuilder(int capacity) {  
  34.         value = new char[capacity];  
  35.     }  


AbstractStringBuilder中定义的变量value,是个字节数组,和String的成员变量value相比,String的value是final修饰,所以StringBuffer和StringBuilde的内容可以变。


在对比下StingBuffer和StringBuilder的实现其他细节,以append()方法为例。

[java]  view plain  copy
  1. public synchronized StringBuffer append(String str) {  
  2.        super.append(str);  
  3.        return this;  
  4.    }  

[java]  view plain  copy
  1. public StringBuilder append(String str) {  
  2.       super.append(str);  
  3.       return this;  
  4.   }  
两者最大的区别是:StingBuffer所有的实现的方法都是 sychronized 修饰的,StringBuilder则不是。



三、String、StringBuffer和StringBuilder的总结


1、概念总结

1).String和StringBuffer、StringBuilder相比,String是不可变的,String的每次修改操作都是在内存中重新new一个对象出来,而StringBuffer、StringBuilder则不用,并且提供了一定的缓存功能,默认16个字节数组的大小,超过默认的数组长度时,则扩容为原来字节数组的长度*2+2。
2).StringBuffer和StringBuilder相比,StringBuffer是synchronized的,是线程安全的,而StringBuilder是非线程安全的,单线程情况下性能更好一点;使用StringBuffer和StringBuilder时,可以适当考虑下初始化大小,较少扩容的次数,提高代码的高效性。

2、使用场景总结

1).如果要操作少量的数据用 = String

2).单线程操作字符串缓冲区 下操作大量数据 = StringBuilder

3).多线程操作字符串缓冲区 下操作大量数据 = StringBuffer






猜你喜欢

转载自blog.csdn.net/qq_35888875/article/details/78636103