首先StringBuilder和StringBuffer的出现是因为字符串的拼接,用String拼接字符串也是可以的,但是效率很低,因为每次拼接一个字符串要产生相当于3个对象,如下:
String类中所有对字符串的改变都会产生一个新的对象,不会对字符串本身进行操作,所以str是一个对象,abc是一个对象,拼接好的str又是一个新的对象,所以一共有3个对象,如果写成一个for循环在里边进行字符串的拼接可以想象,效率是很低的,因为创建对象也是需要时间的。
其实在String进行拼接的时候,底层是有一个StringBuilder然后调用append方法来帮我们完成拼接的,如下代码:
这个代码的效果和刚才的String进行拼接是一个效果,只是这个是String底层做的事情,首先StringBuilder先加入两个对象,然后完成拼接后再把这个StringBuilder这个对象变成string类型的。要算上StringBuilder这个对象就有4个对象了,所以在拼接的过程中产生了很多的对象。
就有了StringBuilder这个类,我现在用一个StringBuilder对象,用StringBuilder的append方法进行拼接,这个时候只有一个对象,进行拼接,效率会很高,那为啥append不会产生新的对象:
可以看到源码,它返回的是this,返回的是当前对象。
所以来介绍下StringBuilder这个类,它也是一个不能被继承的类,它里面有的方法String类中是没有的,String类中有的方法它也是没有的,入reverse字符串的逆置,还有 append,所以String和它的区别:
String进行字符串的改变是要产生新的对象的,而StringBuilder不会产生临时对象,如append方法,还有就是这两个类型不能直接进行转换,是要用append方法或者toString方法来完成转换的。
再来看下StringBuffer这个类:
使用这个类创建一个字符串也是没有问题的,和StringBuilder没啥区别,也可以append,
区别就在这里,StringBuilder的构造方法没有sychronized,可以理解为这个东西就是一个锁,在我们上厕所的时候是需要关锁的,如果不关锁,那不是别人也可以进来了吗,sychronized就是这个锁,StringBuffer这个类是用在多线程中的,这里涉及到线程安全问题,大概就是多线程的调度是随机的,不确定的,所以在写多线程代码的时候也就容易产生bug,那么如何减少一些多线程的bug呢,加上一个锁,就说明这个线程正在占用系统的这一块资源,别的线程就进不去,就无法在CPU核心上跑起来,等这个线程结束了,这个锁也就i打开了,此时别的线程就可以进来了(我也没学到加锁呢,这块是自己的理解)
但是我以后在多线程中直接用StringBuffer不完了,也是不可取的,因为在操作系统中,频繁的加锁和解锁,都是需要耗费资源的,所以这几个类都是在某些需要的场景下进行使用的。
这个就是StringBuffer和StringBuilder还有String的区别。