java stringbuffer相等_分析java面试题《String、StringBuffer和StringBuilder的区别》

这几天基本上都在给大家分析一些面试题。

希望通过一些比较具体化,形象化的描述来让大家能理解这些比较抽象的东西。

今天就给大家分析下String、StringBuffer和StringBuilder的区别。

01String对于StringBuffer和StringBuilder来说的区别

先说说String和其他两个的区别吧。刷面试题的朋友肯定能说出来String声明的对象是不可变对象,其他两个类声明的对象是可变的对象。

那String怎么就是不可变的了呢?

让我们来看看String类的源码吧。

afad2cc67ee0ac50cbddc64e12cccaa6.pngString类的源码

可以看到String类是通过内部的一个char数组实现的。类和类内的属性都是用final修饰的。

看过我前面写的《理解java的final、finally以及finalize》这篇文章,就会知道用final修饰的的变量在首次赋值后是不能被修改的。所以String类声明的对象就是不可变的了。

我们还来打个比方。

通过“String 印刷匠张三”这样声明的变量,这个印刷匠张三使用的技术比较古老,是通过雕版印刷来实现的。

当我们提出一个需求“印刷匠张三="大吉大利"”时,印刷匠张三会去雕刻一张新版,内容是“大吉大利”。

而当我们又提出一个需求“印刷匠张三="今晚吃鸡"”时,刚才雕刻的雕版就不能用了,印刷匠张三会再去雕刻一张新版(新建对象),内容是“今晚吃鸡”。

而StringBuffer和StringBuilder就不一样了,他们使用了比较新的技术,活字印刷。

拿StringBuffer举例来说。

遇到“StringBuffer 印刷匠李四=new StringBuffer("大吉大利")”这样的需求时,这个印刷匠李四会组合好“大吉大利”的内容提供出来。

而当遇到“ 印刷匠李四= 印刷匠李四.append("今晚吃鸡")”这样的需求时,印刷匠李四不是重新去雕版(不用新建对象),而是在原来的基础上继续拼装“今晚吃鸡”。

c96b48c7148685a17f24e19b8b6e9cf2.png

通过这个例子应该好理解多了吧。

02StringBuffer和StringBuilder的区别

通过百度能搜索到好多好多说她们两个区别的文章。

看过的朋友应该都知道了StringBuffer是线程安全的,而StringBuilder不是线程安全的。

那为什么是这样的呢。那是因为在StringBuffer的方法上使用synchronized做了修饰。用synchronized修饰的方法都必须同步访问。

打一个比方有一个食堂(相对于被synchronized修饰的方法),这个食堂用synchronized做了修饰。这样这个食堂同时只能让一个人吃饭。

每个顾客要来吃饭,要先验证一下食堂有没有别人在用,如果没有才可以进去吃。如果食堂有人在用,那必须要等在用的人用完,才可以进去吃饭。

那StringBuilder为什么就不是线程安全的呢。

因为StringBuilder的方法没有用synchronized进行修饰。

我们还打个比方吧。

有一面墙上写了数字1,然后由两个人(两个线程)同时去修改数字,修改的改则是将墙上的数字擦去后并加1写到墙上。

如果是按照synchronized修饰的效果的话,两个人(线程)是不可以同时去重写墙上的数字的,只能轮流来,最后墙上的数字会是3。

但是如果不用synchronized修饰的话,则能同时去改。这样就有可能会有两个人同时看到墙上是1,然后都去把墙上数擦掉,然后写2。

这样的结果就是不正确的了。

所以StringBuilder不是线程安全的。

但是如果不存在多线程调用的情况时,因为StringBuilder是不需要做调用方法前的同步处理的,所以执行效率是要高于StringBuffer的。

好了,今天就讲这些吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值