字符串储存的内存原理
直接赋值会复用字符串池中的常量
new出来不会重复,而是开辟一个新的空间
==比较的到底是什么
基本数据类型比较数据值
引用数据类型比较数据的地址值
字符串拼接的底层原理
拼接的时候没有变量
public static void main(String[] args) {
//拼接的时候等号的右边没有变量
String s = "a"+ "b"+"c"+"d";
System.out.println(s);
}
}
拼接的时候没有变量都是字符串,会触发字符串的优化机制,在编译的时候就已经是最中的结果了
这时候运行的结果就是 s = “abcd”,跟直接赋值是一样的
拼接的时候等号的右边是有变量的
public static void main(String[] args) {
//拼接的时候等号的右边有变量
String s = "a";
String s1 = s + "b";
String s2 = s1 + "c";
System.out.println(s2);
}
JDK8以前底层会使用StringBuiler

运行图解释
main方法进栈
执行main方法里面的第一行代码String s = "a";
在堆内存中的串池中会生成一个a,s记录的就是a的地址值
接下来执行String s1 = s + "b",这里的b也会在串池中生成
在堆内存中会创建一个stringbuilder对象,然后会使用append方法,将a和b都放进stringbuiler方法中,接下来会使用tostring方法将其变成一个字符串,此时字符串的内容就是ab了;
接下来的s2也是同样的原理。
缺点:
在上面的代码中写的每一行代码都会创建一个stringbuilder对象,此时的效率就是会比较的慢了
JDK8以后字符串的拼接原理
会预估字符串的长度并创建一个数组
然后根据数据的长度会把数据存储在数组里面,最后将这个整体变成一个字符串
stringbuilder提高效率的原理图解
还是看这样的一行代码
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("aaa");
sb.append("bbb");
sb.append("ccc");
System.out.println(sb);
}
首先还是main方法进栈,在main中创建一个stringbuilder对象,然后会在堆内存中开辟一个空间
接着会将堆内存中开辟的空间赋值给sb;
然后再main方法中会调用append方法将aaabbbccc添加到sb之中
stringbuilder源码分析
默认创建一个长度是16的字节数组
添加的内容长度小于16,直接存
添加的内容长度大于16(原来的容量*2+2)
如果扩容之后还不够,以实际的长度为准