String对象的探究
- 1. 前言(String)
- 2. new String()到底创建了多少对象(java8举例)?
- 2.1. new String("abc"):2/1
- 2.2. String str = “a” + "b" + “c”:1
- 2.3. String abc ="a"+ new String("bc"):5
- 2.4. String str = new String(“a”) + new String(“b”):6
1. 前言(String)
- 内部结构
jdk8及以前,使用的是char[]jdk8以后,使用的是byte[]+字符编码标识
- 不可变性
- 通过字面量的方式给一个字符串赋值,是直接声明在字符串常量池中
- 字符串常量池中是不会存储相同内容的字符串的
- 内存分配
jdk6及以前:字符串常量池存放在永久代jdk6之后:调整到了Java堆内
intern()方法jdk6及以前:如果字符串常量池中有,则不会放入,而是返回已有的字符串常量池中对象的地址;如果没有,会把此对象复制一份(创建一份新的),放入字符串常量池中,并返回字符串常量池中对象的地址jdk6之后:如果字符串常量池中有,则不会放入,而是返回已有的字符串常量池中对象的地址;如果没有,会把此对象的引用地址复制一份,放入字符串常量池中,并返回字符串常量池中的引用地址
2. new String()到底创建了多少对象(java8举例)?
2.1. new String(“abc”):2/1
- 如果在常量池中
“abc”不存在,则分别在常量池中和堆中创建“abc”字符串常量以及字符串实例对象 - 如果在常量池中
“abc”不存在,则只在字符串实例对象 - 无论如何都会创建字符串实例对象
2.2. String str = “a” + “b” + “c”:1
- 这个
“a + b + c”在底层会在编译阶段编译为“abc”,JAVA在编译器编译时,常量与常量的拼接会得到编译优化为“abc”并放入常量池中
2.3. String abc =“a”+ new String(“bc”):5

- 这里假设字符串常量池中无数据
- 只要不是单纯的直接使用字符串字面量相加就会在运行时产生一个
StringBuilder对象用于字符串连接,且不会进行此处的字符串编译优化 - 根据如上图所示,会产生:
StringBuilder、字符串常量a、string(”bc“)、bc字符串常量、StringBuilder.toString()方法:会new一个String(“abc”)对象,一共五个对象
2.4. String str = new String(“a”) + new String(“b”):6
* 这里假设字符串常量池中无数据
- 根据如上图所示,会产生:
StringBuilder、string(”a“)、字符串常量a、string(”b“)、b字符串常量、StringBuilder.toString()方法:会new一个String(“ab”)对象,一共六个对象







![P9232 [蓝桥杯 2023 省 A] 更小的数](https://img-blog.csdnimg.cn/img_convert/939892d94daa4b702b6d28b9277d6175.png)











