String&StringBuffer&StringBuilder

面试官:平时拼接字符串用StringBuffer还是StringBuilder,说说选择的理由。

 

首先,StringBuffer是Java1.0版本就有的类,几乎它的所有方法都是同步的(被synchronized修饰);StringBuilder是Java1.5引入的新类,它的方法都没有加同步锁。

它俩的方法基本一样,区别就是一个方法几乎都是同步的另一个方法都没同步。

那么,为什么开始Java1.0时有了StringBuffer后面到1.5又引入了一个StringBuilder呢?

这是因为Java语言开发的初期,Java的作者考虑问题也不是那么严谨,认为StringBuffer所有的方法都加上同步锁的写法是正确的。到后面他们才意识到,不应该强制给StringBuffer的方法全部加锁,因为加锁会严重影响程序性能。应该让用户自己去决定,需要同步的地方让用户自己去加锁。

那么我们知道,程序设计最基本的几个原则(solid)有一个是ocp,开闭原则——程序应该对扩展开放对修改关闭,即允许你新增类但不允许你修改已有的类。为什么呢?这也很好理解,拿jdk来说,你发布了jdk1.0版本就会有很多人用的,你把jdk基本方法一修改,那得多少项目和程序跟着修改啊,这是整个语言基础层面的,很可怕的。

那么怎么办呢?jdk作者选择新加一个类叫StringBuilder,它几乎和StringBuffer有完全一样的方法,唯一做的就是把所有方法上的同步锁去掉。jdk作者的意图也很明显了:需要同步的地方你就选用StringBuffer,不需要同步的地方你就选用新类StringBuilder。这样就把加同步锁的选择权给了用户,选择合适的。至于jdk1.5之前的程序,如果你对程序性能有要求就修改代码,如果不在乎这儿的性能还可以选择继续使用StringBuffer。

 

String呢,它是一个类,看源码它被 final 关键字修饰,那么它不能被修改。你看String的源码里所有的方法(subString、concat、replace等)最终返回的都是一个新的字符串(new String())。

记住:所有对String的操作最终返回的都是一个新的String,原字符串并没有变。

String还有个特别的地方,就是有个常量池,如下:

String a = "test"; // 去常量池中查找,看有没有"test",有就把a的引用指向"test"

String b = new String("test");//在堆空间创建一个新的对象,赋值给b

String d = "this is " + "test";//去常量池找 "this is test"

String e = "this is" + b;//在堆空间创建一个新的对象"this is test"

posted @   shog808  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示