目录
♦️字符串存储的内存原理
🎏字面量字符串对象
🎏构造函数声明字符串对象
♦️==比较的是什么
🎏基本数据类型
🎏引用数据类型
♦️字符串拼接的底层原理
🎏拼接的时候没有变量参与
🎏拼接的时候有变量参与
♦️StringBuilder提高效率原理图
🎏常见面试题
♦️StringBuilder源码分析
🎏当字符串长度未超出16时
🎏当字符串长度超出16未超出34时
🎏当字符串长度超出34时
♦️总结
♦️字符串存储的内存原理
🎏字面量字符串对象
String name="zhangsan"; //直接赋值类
🎏构造函数声明字符串对象
String name=new String("zhangsan"); //构造方法声明字符串对象
new出来不会复用,而是开辟一个新的空间
♦️==比较的是什么
🎏基本数据类型
基本数据类型比较的是数据
int a=10; int b=120; System.out.println(a==b); //false
🎏引用数据类型
引用数据类型比较的是地址值
String s1=new String("abc"); Strinh s2=new String("abc"); System.out.println(s1==s2); //false
♦️字符串拼接的底层原理
🎏拼接的时候没有变量参与
当拼接的时候没有变量参与时,字符串会触发字符串的优化机制。复用串池中的内容,即在编译的时候就已经是最终的结果了
🎏拼接的时候有变量参与
会创建新的字符串,浪费内存。
注:字符串拼接的时候,如果有变量:
- JDK8以前:系统底层会自动创建一个StringBuilder对象,然后再调用其append方法完成拼接。拼接后,再调用其toString方法转换为String类型,而toString方法的底层是直接new了一个字符串对象
- JDK8版本:系统会预估要字符串拼接之后的总大小,把要拼接的内容都放在数组中,此时也是产生一个新的字符串。
♦️StringBuilder提高效率原理图
StringBuilder是一个内容可变的容器
所有拼接的内容都会王StringBuilder中放,不会创建很多无用的空间,节约内存。
🎏常见面试题
下列代码的运行结果是:
import java.util.Scanner; public class Main { public static void main(String[] args) { String s1="abc";//记录串池中的地址值 String s2="ab"; String s3=s2+"c"; System.out.println(s1==s3); } }
false:
原因:在本体代码中,在拼接时有变量参与,拼接后,调用其toString方法转换为String类型,而toString方法的底层是直接new了一个字符串对象。因此,String s3相当于是新new了一个对象,记录的是地址值,所以两个不相同
♦️StringBuilder源码分析
🎏当字符串长度未超出16时
如图StringBuilder的默认容量为16
import java.util.Scanner; public class Main { public static void main(String[] args) { StringBuilder sb=new StringBuilder(); //容量:最多装多少 //长度:已经装了多少 sb.append("abc"); System.out.println(sb.capacity()); System.out.println(sb.length()); } }
🎏当字符串长度超出16未超出34时
import java.util.Scanner; public class Main { public static void main(String[] args) { StringBuilder sb=new StringBuilder(); //容量:最多装多少 //长度:已经装了多少 sb.append("abcdefghigklmnopqrstuvwxyz"); System.out.println(sb.capacity()); System.out.println(sb.length()); } }
🎏当字符串长度超出34时
StringBuildre的最大容量就是字符串的长度
import java.util.Scanner; public class Main { public static void main(String[] args) { StringBuilder sb=new StringBuilder(); //容量:最多装多少 //长度:已经装了多少 sb.append("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");//36; System.out.println(sb.capacity()); System.out.println(sb.length()); } }
♦️总结
扩展底层原理1:字符串存储的内存原理
- 直接赋值会复用字符串常量池中的
- new出来不会复用,而是开辟一个新的空间
扩展底层原理2:==号比较的到底是什么?
- 基本数据类型比较数据值
- 引用数据类型比较地址值
扩展底层原理3:字符串拼接的底层原理
- 如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串。
- 如果有变量参与,会创建新的字符串,浪费内存。
扩展底层原理4:StringBuilder提高效率原理图
- 所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存
高