理解Java的字符串,String、StringBuffer、StringBuilder有什么区别?

今天会来说一下日常使用到的字符串,虽然在生活中会经常使用到,但是在编程语言中却是一个特殊的存在,今天的问题就是,String、StringBufer、StringBuilder有什么区别?

初步了解

简单说一下区别:

String:Immutable类型,无法对于自身拼接,裁剪,加长,只能产生新的String对象,所以在使用效率上对于性能会有明显的影响。

StringBuffer:解决了上面所说的无法拼接的问题,StringBuffer是mutable类型的,可以用内部的append或者add给末尾或者中间添加字符串,不但是线程安全的,但带来了额外的性能消耗,所以除非强调线程安全,否则还是要使用StringBuilder的

StringBuilder:和StringBuffer相比,去除了线程安全,带来的性能的节省。

几乎所有的应用开发都会涉及到String 的各种操作,但是如果字符串操作不当,就会产生各种各样线程安全方面的问题。

知识扩展

1.字符串设计和实现考量

上面提到过,String是Immutable类型的,无法进行拼接操作,原生的字符串操作保证了字符串是线程安全的,因为无法对其内部进行修改,只能造出一个新的对象。

而像上面介绍的一样,StringBuffer是可延长的,只不过它的线程安全全都是依靠简单粗暴的synchronized关键字实现的,非常直白。就像HashTable一样,hhh。

为了达到可以修改字符序列的目的,StringBuffer和StringBuilder都使用了构建内部数组,二者都包含了基本操作,区别仅仅在于线程安全。

另外,这个内部数组应该创建成为多大的才是最完美的呢,初始值为16,如果超过的话,就会执行arrayCopy操作,构建最恰到好处的容量才是节省成本,提高性能的根本。

那么,对于字符串拼接,我们可以用加号来实现,也可以用StringBuilder实现,有什么区别吗?在JDK8的时候,字符串的加法,自动会被转换为StringBuilder识别进jvm,但是在jdk9中,则会使用StringConcatFactory进行字符串拼接。

2.字符串缓存

我们在进行应用开发的时候,实际上,大多数都是字符串,就像经常操作orm的就会知道,不仅仅是字符串,还是重复的,那么消除这些重复的字符串带来的额外的性能困扰,java也提供了一定的优化方法。

String 在java6之后提供了intern()方法,目的是让jvm将重复字符串进行缓存,就像,mysql的查询缓存一样,当找到类似或者一样的字符串的时候就直接return了。

但是,上面的intern方法,并不推荐使用,为什么呢?了解过GC调优的或许就知道了,新生代转化为老年代之前会经过不断的垃圾回收,即使到了老年代也仍然有老年代GC,但是这个intern方法产生的缓存,是永久代,不会被gc回收,所以就会产生OOM,只有Full GC才能对其影响,但有什么用呢?

所以后续版本,治标不治本,但是确实也能用,jdk8提升了一定的最小默认缓存。当然也可以手调。

此外,还有一个缺点就是,我们无法提交标记重复率高的字符串,所以一开始交给jvm去进行新生代调用次数统计的时候,也很麻烦。

在运行时,字符串的一些基础操作会直接利用JVM内部的Intrinsic机制,往往运行的就是特殊优化的本地代码,而根本就不是Java代码生成的字节码。但是对于Intrinsic的发生机制还是可以好好研究的。

3.String自身的强化

如果仔细观察的话就会知道,以往的String都是用char数组来存取数据,但是char占用 两个字节,很多情况下,存取的时候一个单位占用不到两个字节,就会浪费。

在Java 9中,我们引入了Compact Strings的设计,对字符串进行了大刀阔斧的改进。将数据存储方式从char数组,改变为一个byte数组加上一个标识编码的所谓coder,并且将相关字符串操作类都进行了修改。

但是虽然有了这么大的改变,本身使用却没有影响,所以说这个改动是很底层很透明的,绝大多数情况不需要改动已有代码。

只不过从char数组存储换成了byte存储之后,存储总容量降了一半,但虽说降了一般,理论的极限还是很难达到的,所以没什么影响的说。

但是从使用角度上来说,替换成byte之后的确是占用了更小的内存有了更快的速度。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值