java中String、StringBuffer、StringBuilder的区别

  • 在java开发中,String类是我们经常用到的一个类,所以为了提高开发效率,jdk提供了一个字符串常量池,方便我们的使用。那么什么是字符串常量池呢,就是一个存储字符串的空间,例如
    String s = “abc”; **“abc”**这个字符串就是存储在字符串常量池中,也就是建了一个 “abc” 字符串对象,而变量s中只是一个内存地址,指向字符串常量池中的 “abc” 字符串。如果要再次用到 “abc”
    字符串,就直接在字符串常量池中获取,而无需在新建一个 “abc” 字符串对象。

  • 那么同样是创建了一个字符串对象,String s = “abc”; 与 String s = new String(“abc”);
    有什么区别呢?答案是:前者只创建了一个对象,在字符串常量池中,变量s在栈内存中,是一个指向字符串常量池中的 "abc"
    字符串位置的内存地址;而后者创建了两个对象,一个在字符串常量池中,一个在堆内存中,堆内存中的对象存储的是指向字符串常量池中的
    "abc" 字符串位置的内存地址,引用s在栈内存中,也是一个内存地址,不过是指向的堆内存中的对象。

  • String类我们也经常用来进行字符串拼接,例如:

    在这里插入图片描述

  • 但是这种通过 “+”
    进行字符串拼接的方式会创建过多的字符串对象,而给字符串常量池造成压力,为了避免这种情况,我们通常使用StringBuffer或者StringBuilderappend()方法来进行字符串的拼接。
    通过源码可以看到,字符串是以char[]数组的形式存储的
    在这里插入图片描述
    在这里插入图片描述
    注意这里的char[]数组是以final关键字修饰的,即只要创建了这个数组,它就不可变了,这也是为什么用String进行字符串拼接会创建多个字符串对象的原因。
    我们再来看看StringBuffer类中的源码
    在这里插入图片描述
    可以看出在创建StringBuffer对象的时候,内部会调用父类中的方法,初始化char[]数组的容量为16
    在这里插入图片描述
    在这里插入图片描述
    然后再来看看拼接字符串的append()方法
    在这里插入图片描述

    会调用父类中的append()方法,点进去可以看到
    在这里插入图片描述
    再点进getChars(),可以看到如果数组容量不足,内部会进行自动扩容(System.arraycopy())
    在这里插入图片描述

  • 但是为了优化StringBuffer()的性能,在创建StringBuffer对象的时候尽可能给定一个合适的初始化容量,减少底层数组的扩容次数 在这里插入图片描述

    • StringBuilderStringBuffer一样可以进行字符串拼接,不过一个是线程不安全的的,效率高;一个是线程安全的,效率低(有synchronized修饰符)
    • 在这里插入图片描述
    • 在这里插入图片描述 具体原因也可以看源码…
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值