java源码解读之String,StringBuilder,StringBuffer

由于最近正好毕业了,正在找工作~~~参加了几场面试,发现好多公司都会问String,StringBuilder,StringBuffer三者之间的区别~~说实话,以前没了解过,所以不知道,其实网上很多都有相关的介绍,但是不理解为什么!所以今天就打算从源代码看看三者之间的区别~~~

首先看一下String的源码:




我们可以看出,String是一个final类型的一个类,不可以被继承。同时,String底层由char数组实现的~~~


我们先来看一下这个代码


String s1 =new String("abc")

以上会产生几个对象呢?

这是面试中经常出现的一个问题~~~

答案是:两个

为什么呢?我们来看一下源码:

 public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

我们可以看你出来,String s1=new String("abc");其实就是将“abc”产生一个对象,并且把该对乡复制给s1对象~~~

这就是产生两个对象的原因!!!



同时呢,String产生之后的长度是不可改变的~~~那就有同学问了,s1+=s2是怎么回事?


其实,那是s1+s2产生一个新的String对象s1,原来的s1对象已经被废弃掉了~~~~

其实,这样效率非常的低的~~

而且在多线程的环境下是非同步的,也就是不安全的~~

这就是好多都推荐用StringBuffer或者StringBuilder的原因了~~~


我们看一下StringBuffer的源码:



StringBuffer继承于absractStringBuilder

创建方式有四种,其 中StringBuffer sb=new StringBuffer("qqqqq")的创建方式,是将String的长度+16产生一个新的StringBuffer对象,然后在调用apppend()方法将“qqqq”追加到StringBuffer对象中,那我们看一下append()的源码:

 public synchronized StringBuffer append(String str) {
        super.append(str);
        return this;
    }
  public AbstractStringBuilder append(String str) {
        if (str == null) str = "null";
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0)
            expandCapacity(minimumCapacity);
    }

void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();
            newCapacity = Integer.MAX_VALUE;
        }
        value = Arrays.copyOf(value, newCapacity);
    }


append()方法内部直接就是调用父类的absractStringBuilder中的append(),在父类的append()中,首先判断追加后数组的长度是否超出现有长度,超出的话,就将

现有的数组产度扩充为:现有长度*2+2  ,然后在将内容复制到新数组中!!

可见,StringBuffer对象是可变的,长度可变不唯一,递增规则就是:现有长度*2+2

这样的话,效率上事要比String要高很多的~~~~

同时,StringBuffer的所用方法都是由synchronized关键字修饰,是线程安全的。



我们接下来看一下StringBuilder的源码:



是不是很熟悉阿?对!StringBuilder和StringBuffer在实现上基本一致,唯一一点区别就是StringBuilder是线程不安全的!!

这就是为什么两者的效率为什么基本一样的原因~~~~


OK,这样想必大家就对三者之间的关系有所理解了把~~~












  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值