一、字符串
1、String 对象是不可变的,String 类中每一个看起来会修改String 值的方法,实际上都是创建了一个全新的 String 对象,以包含修改后的字符串内容,而最初的String 对象则丝毫未动。每当把 String 对象作为方法的参数时,都会复制一份引用,而该引用所指的对象其实一直待在单一的物理位置上,从未动过。
2、Stringbuilder中 append ,比如 append 一个 “str” ,其实 Stringbuilder 维护了一个 char[ ],用于存放字符串,当有 append 请求时先会重新 new 一个 char[ ]数组,这个数组长度为老字符串长度加需要添加的字符串长度的和,完了后把老容器里面数据通过 System.arraycopy 方法 copy 到新容器,然后调用 “str” 这个 String 里面的 getChars,这个方法里面又调用了 System.arraycopy 把自身 “str” 这个数据 copy 到 Stringbuilder 的 char[ ],这样就完成了一次添加。
3、String的 “+” 来拼接字符串真的就效率比 StringBuilder 来拼接低那么多么?网上有很多答案都不是很准确或者没说明原因,但是这本书的作者 反编译了字节码发现其实 “+” 操作编译的时候被优化成了 StringBuilder 的 append 操作,所以类似 String str =“abc” + “def” + ”ghj” 这种操作效率和 StringBuilder 是一样,当然只是这种情况的时候。下图是反编译的代码:
当然,当如下这种情况的时候就会产生很多的 String 临时对象:
String str = “abc”;
str += “efg”;
str += “vvv”;
上面没 ”+“ 一次还有一个新的 Stringbuilder 产生,每 “ = ” 一次 Stringbuilder就会 toString 产生一个新的 String对象,于是大量操作的话中间会有大量的临时对象产生。所以一旦是这种业务的话还是用 Stringbuilder 为妙,尽管 Stringbuilder 每次 append 也会新开辟一个内存空间,但一对比也好了很多。还有一种更加优化的 Stringbuilder,可以避免每次 append 时 new char[],那就是在 new StringBuilder 的时候传入你最终需要生成的字符串长度,前提是你得提提前知道你最终的长度。