String,StringBuffer,StringBuilder比较

来源:互联网 发布:java web 2年水平 编辑:程序博客网 时间:2024/05/20 06:53

String对象是不可变得,每次对String对象的操作其实都是生成一个新的对象,这样会浪费大量的内存。StringBuilder和StringBuffer对象是可变的,但StringBuffer是线程安全的,StringBuilder是线程不安全的。

1.      String类分析

 (1)示例1:

 String s=”abcde”;

 System.out.println(s);

 s=”ABCDE”;

 System.out.println(s);

 输出结果:

 abcde

 ABCDE

 说明:这里生成了两个String对象,”abcde”和”ABCDE”,s开始指向”abcde”,第二次s指向了一个新的对象”ABCDE”,而原来的”abcde”对象是没有改变的。

(2)String的源码分析

  public final class String

    implements java.io.Serializable, Comparable<String>,CharSequence

{

    /**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;

………..

  }

 可以看出来String类的成员变量value,offset,count是被private,final修饰的,也就是说外部的类不能访问String类的这些成员变量,而且由于变量是被final修饰的,所以这三个变量一旦在String类内被初始化,值就不可以再被改变,这些变量类型的设置保证了String对象是不可变的。

(3)那么String类中replace(),toLowerCase(),toUpperCase()这些方法是如何实现的?

刚开始也有疑问,试了如下的代码:

示例2:

String s="abcde";

 s.toUpperCase();

 System.out.println(s);                 

 s=s.toUpperCase();

 System.out.println(s);

输出结果:

abcde

ABCDE

说明:s.toUpperCase(),s还是指向”abcde”,s指向的内容是没有改变的,而

s= s.toUpperCase()返回了一个新的字符串对象”ABCDE”。阅读String类源码查看toUpperCase()方法:

public StringtoUpperCase() {

          returntoUpperCase(Locale.getDefault());

             }

public String toUpperCase(Localelocale) {

         ……

          returnnew String(0, count+resultOffset, result);

             }

发现最后生成的是一个新的String对象。这也就解释了示例2代码所运行的结果。

2.StringBuffer和StringBuilder分析

   StringBuffer和StringBuilder类都继承AbstractStringBuilder类,实现的功能基本相似,而StringBuffer是线程安全的,StringBuilder不是线程安全的,所以在使用过程中,StringBuilder操作的速度略快于StringBuffer的。

(1)StringBuffer和StringBuilder对象是可变的。

  StringBuffer和StringBuilder类都继承自AbstractStringBuilder类,读AbstractStringBuilder类的源码会发现其成员变量没有final修饰,这也是和String类成员变量的最大区别,使得其value数组的值是可变的。

  abstract classAbstractStringBuilder implements Appendable, CharSequence {

    /**

     * The value isused for character storage.

     */

    char[] value;

    /**

     * The count isthe number of characters used.

     */

int count;

……

}

阅读其中的append(String),insert(int, int),reverse()等方法源码,会发现其最后都返回的是原对象,也就是其修改的是value数组的本身值。这也就是StringBuffer和StringBuilder对象是可变的原因。

(2)StringBuffer是线程安全的,StringBuilder不是线程安全的。

 阅读两者源码会发现两者的实现差异,StringBuffer类的成员方法几乎都使用了synchronized关键字约束,使得StringBuffer类是线程安全的,而StringBuilder成员方法没有synchronized关键字约束,是线程不安全的。

 

以上时学习中对String、StringBuffer、StringBuilder的一些理解,可能还有很多分析不到位的地方,希望和大家共同学习。

 


0 0
原创粉丝点击