### 本系列帖子为鼠鼠复习八股巩固记忆和个人理解所写,如有错误纯属本人实力不佳,欢迎各位大佬阅读指正 ###
1 String StringBuilder String Buffer 的区别
String :
核心特性:不能更改,当字符串对象创建后,进行拼接.截取.替换等操作时会创建一个新的String对象,原本的String对象不发生修改,若有大批量字符串进行以上操作时会导致,频繁创建对象使其影响性能,再线程安全性上由于不对本身进行操作所以天然安全
String Builder :
核心特性:可以更改,但线程不安全,由于方法没有添加synchronized(同步锁)导致在并发场景多线程同时操作会导致数据错乱,但正因为没有锁的加入性能上更加优
StringBuffer :
核心特性:可以更改,线程安全绝大部分方法已经被(同步锁修饰),但因加入了锁会有响应的性能开销导致性能略差与StringBuilder
追问:
String为什么不设计为可变的呢?
1.线程安全
不可变对象线程并发访问无需同步所以不会出现类似线程安全问题
2.哈希码可以缓存提高HashMap性能(不可变是String适合做Map Key 的根本原因)
String内部会缓存hashCode,只计算一次后续直接复用
3.字符串常量池复用(JVM中一块专门区域),大幅节省内存
因为不可变,相同可直接共享同一个对象
4安全性高
文件路径,网络URL也是String传递,不可变可以防止被修改保证安全
2.String s = new String ("abc") 创建了几个对象?String s="a"+"b"+"c"; 创建了几个对象?
String s = new String ("abc")在执行时,只要有双引号就回去常量池寻找如果没有则在常量池创建一个,同时new String 又创造一个String实例 ,所以如果常量池没有则创建两个,如果有则创建一个。
String s="a"+"b"+"c"; 常量池无则创建一个,有则不用创建。
(注:这种"a"+"b"+"c" 常量+常量形式会先将拼接为"abc",
若是变量+变量/变量+常量会创建一个Stringbuilder只做append最后toString生成一个String,
但在循环中不要使用+=进行拼接会导致反复创建StringBuilder导致性能问题,
可在循环外创建一个Stringbuilder循环内使用append即可)
3.如何比较两个字符串的内容是否相等?为什么不能用 ==?
使用 equals () 方法,String类已经重写了Object的equals()方法,不是比较地址而改为逐个比较字符内容,==比较的是变量保存的内存地址不是字符串内容,对于基本类型 (int char….)比较的值,对于引用类型(对象 String…)==比较的是内存地址如果使用==会出现即时两个字符串内容相同仍然出现false现象,本质上是因为两个对象的地址不相同,==无法实现比较字符串内容,故使用equals()方法
4.intern () 方法的作用
它是String类中的一个本地方法
核心作用:把当前字符串对象加入到字符串常量池,并返回常量池中的对应实例
效果:保证内容相同的字符串,全局公用一个对象
存在原因:有些字符串,运行时才知道内容无法直接写字面量,同时new String不能自动进池,所以使用intern()使其进池复用。
注:只有 "…" 双引号写死的字符串JVM 才会自动放进常量池。
凡是 运行时算出来、拼出来、new 出来 的字符串都不会自动进池。


