1.StringBuilder(JDK8底层也是char[]数组,但是没有被final修饰)的基本应用。
Stringbuilder和Stringbuffer继承自同一个顶层类AbstractStringBuilder,所以成员变量不是finall修饰的。
无参数的构造方法,初始长度是16。
扩容后新数组长度=旧数组的长度*2+2。
2.String(的成员变量也是char[]数组,但是被final修饰的,不可被继承)的+操作底层是StringBulider。
- String对象在进行“+”操作的时候,其实调用了StringBuilder对象的append()方法
先来看String a,“Java”+“!”在String编译期间进行优化,优化结果为“Java!”,而该值在常量池中已经存有一份,因此a也指向了该常量池中的字符串,因此 a1 和 a 相等,输出ture。
在对 b 和 “!”进行相加的过程中,b 其实是在堆中创建了一个StringBuilder对象,调用append()方法加入,而“!”是常量池中的字符串,两者引用明显不同,因此输出false 。
用反编译来看一下直接字符串相加和使用引用相加的区别:
1).可以看到,在第0行的时候,字符串就已经变成了Java!了,说明“Java”+“!”在编译的期间就已经进行了优化
2).第9行开始,也就是在执行b+“!”这个语句,当执行b的时候,创建了一个StringBuilder对象,实例化StringBuilder对象,从常量池中推送字符串“!”,利用append方法拼接“!”,最后调用append的toString方法。
3).关于相加的效率,字符串常量效率高,因为编译器不会对引用变量加以优化
3、String的+操作底层已经是String Builder了,那我们还有必要再学习或者使用String Builder吗?
有必要👇🏻:
当用String类拼接字符串时,每次都会生成一个String Builder对象,然后调用两次append()方法把字符串拼接好,最后通过StringBuilder的to String()方法new出一个新的字符串对象 。也就是说每次拼接都会new出两个对象,并进行两次方法调用,如果拼接的次数多了,创建对象所带来的时延会降低系统效率,同时还会造成巨大内存浪费
StringBuilder拼接字符串就简单多了,直接把要拼接的字符串放到栈顶进行append就好了,除了开始创建了StringBuilder对象,运行时期没有创建过其他对象,每次循环只调用一次append方法,所以效率上来看,拼接大量字符串时,StringBuilder要比String类给力