String | StringBuffer | StringBuilder 比较

  2016的第一天,我决定写一篇博客来纪念这一天,希望一年好运吧。

  String|StringBuffer|StringBuilder这三者在我们学习JAVASE核心API的时候常常出来,而且大多数入门教材都扯了一大堆他们的区别,只是没有讲清楚为什么会有这些区别。

  重申一下三者的区别:

    1.String类:封装不可变字符串;

    2.StringBuilder类:封装可变字符串,并发处理,线程不安全,一般来说处理速度最快;

    3.StringBuffer类:封装可变字符串,同步处理,线程安全,一般来说处理速度慢于StringBuilder类

  下面就这些特性从码源角度来分析为什么会这样。

  1.String类:封装不可变字符串 

public final class String implements java.io.Serializable, Comparable<String>, CharSequence  

  String类底层是由char数组实现的,而char数组在String类中的码源为: private final char value[]; 也就是说String类的对象本质是不可变字符数组,因此我们不能改变String对象的内容。然而String类对象的引用变量如果没有final修饰则是可以改变其存储的地址值的,即引用变量指向的对象可以改变。

  补充:final修饰变量就是指变量中储存的内容不能够被修改。如果是基本数据类型变量,存的是数据内容;如果是引用类型变量,存的是对象地址。当然这两者本质上是统一的,即均为变量的内容,只不过引用变量的内容就是地址值(注:变量本质上就是JVM开辟的内存空间,一个放数据的地方)

  2.StringBuilder类

public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence

  StringBuffer类继承了AbstractStringBuilder类,AbstractStringBuilder类 abstract class AbstractStringBuilder implements Appendable, CharSequence 中关于char数组声明为 char value[]; 因此这个数组内容是可变的,即StringBuilder类封装的是不可变字符串。且AbstractStringBuilder声明了Appendable接口,因此其实现类均必须实现append()方法。当然AbstractStringBuilder类还有replace()、insert()、delete()等非抽象方法,实现类继承即可以使用。

  StringBuilder采用并发编程,而并发编程会导致一个内容同时会被多个线程访问,显然速度会比StringBuffer快,不过这显然是不安全的。想想如果你卡里有1000块,你从ATM机和手机同时取1000,如果是并发处理,那么你将得到2个1000元(前提是你真的是同时处理的),显然这是不安全的嘛,人家银行就亏惨了。而这里的从ATM机取和从手机取就是两个线程,而且StringBuilder分开拿当然要比StringBuffer一起拿速度快。

  3.StringBuffer类

 public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence

  StringBuffer同样也是继承了AbstractStringBuilder类,因此与StringBuilder类一样是有append()、replace()、insert()、delete()等方法,以及关于char数组的声明。简而言之,StringBuffer类和StringBuilder类在大致方向上是一致的。但是StringBuffer的方法都加了"同步锁",即都用了synchronized修饰。因此StringBuffer类:封装不可变字符串,同步处理,线程安全,速度慢于StringBuilder类就很好理解了。

  

  从上面的分析,大致可以知道:

  1)String str;的str引用变量可以指向不同的对象,是由于对象实现的char数组加了final修饰词缘故,而不是str前面有final(如果这样,str不能指向不同对象)

  2)StringBuffer和StringBuilder师出同门。但是StringBuffer是线程安全的,而StringBuilder是线程不安全的。

  

  

原文地址:https://www.cnblogs.com/forget406/p/5093359.html