Java字符串10—字符串相关类的底层原理

文章讨论了Java中字符串的内存管理,包括直接赋值时复用字符串池中的常量和`new`操作创建新对象的区别。对于`==`的比较,基本类型比较值,引用类型比较地址。在字符串拼接时,无变量拼接在编译时已确定结果,而涉及变量的拼接在JDK8之前使用StringBuilder,之后则有更高效的优化策略,预估长度并存储在数组中。StringBuilder的效率提升在于动态扩容,初始长度为16,根据需要进行扩展。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 字符串储存的内存原理

  • 直接赋值会复用字符串池中的常量

  • new出来不会重复,而是开辟一个新的空间

  1. ==比较的到底是什么

  • 基本数据类型比较数据值

  • 引用数据类型比较数据的地址值

  1. 字符串拼接的底层原理

  1. 拼接的时候没有变量

 public static void main(String[] args) {
        //拼接的时候等号的右边没有变量
        String s = "a"+ "b"+"c"+"d";
        System.out.println(s);
    }
}

拼接的时候没有变量都是字符串,会触发字符串的优化机制,在编译的时候就已经是最中的结果了

这时候运行的结果就是 s = “abcd”,跟直接赋值是一样的

  1. 拼接的时候等号的右边是有变量的

    public static void main(String[] args) {
        //拼接的时候等号的右边有变量
        String s = "a";
        String s1 = s + "b";
        String s2 = s1 + "c";
        System.out.println(s2);
    }
  • JDK8以前底层会使用StringBuiler

运行图解释

  1. main方法进栈

  1. 执行main方法里面的第一行代码String s = "a";

  1. 在堆内存中的串池中会生成一个a,s记录的就是a的地址值

  1. 接下来执行String s1 = s + "b",这里的b也会在串池中生成

  1. 在堆内存中会创建一个stringbuilder对象,然后会使用append方法,将a和b都放进stringbuiler方法中,接下来会使用tostring方法将其变成一个字符串,此时字符串的内容就是ab了;

  1. 接下来的s2也是同样的原理。

缺点:

在上面的代码中写的每一行代码都会创建一个stringbuilder对象,此时的效率就是会比较的慢了

  • JDK8以后字符串的拼接原理

  1. 会预估字符串的长度并创建一个数组

  1. 然后根据数据的长度会把数据存储在数组里面,最后将这个整体变成一个字符串

  1. stringbuilder提高效率的原理图解

还是看这样的一行代码

    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        sb.append("aaa");
        sb.append("bbb");
        sb.append("ccc");
        System.out.println(sb);
    }
  1. 首先还是main方法进栈,在main中创建一个stringbuilder对象,然后会在堆内存中开辟一个空间

  1. 接着会将堆内存中开辟的空间赋值给sb;

  1. 然后再main方法中会调用append方法将aaabbbccc添加到sb之中

  1. stringbuilder源码分析

  • 默认创建一个长度是16的字节数组

  • 添加的内容长度小于16,直接存

  • 添加的内容长度大于16(原来的容量*2+2)

  • 如果扩容之后还不够,以实际的长度为准

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值