StringBuffer,StringBuilder以及String

栏目: Java · 发布时间: 5年前

内容简介:今天在网上闲逛,看见他提到的问题也很有深度,然后思考了下,想评论来着。然而评论区太小,写不下,所以单独写在这儿。基本上可以当作快问快答来读…

今天在网上闲逛,看见 @姚冬 的一个 回答

他提到的问题也很有深度,然后思考了下,想评论来着。然而评论区太小,写不下,所以单独写在这儿。

基本上可以当作快问快答来读…

为什么 java 中的string不以\0结尾?

  • \0结尾在很大程度上要求 程序员 写规范的代码,如果写出了不规范的代码,那么很容易就内存越界了。
  • 另外,string的内部存储是char[],而为了内存安全,java数组本来就有一个length属性,这时以\0结尾就是一个多余的设计了。
  • String的内部存储也只能是char[]了,如果是其他的方式,比如通过native内部放一个c风格的数组,那么java代码中的char[]和string的转换就要很多内存拷贝操作了。
  • C语言 设计成\0结尾,是为了减少抽象层,让C语言更加贴近硬件

(在语言设计中,)字符串的长度放哪里,放到起始指针的位置,还是起始指针的前面 ?

  • Java中,String的length也就是数组的length,JLS也只是说明了arraylength字节码,没有规定如何实现
  • 不过Hot Spot的实现是,先元数据,再长度,再具体的内容(比如char[])

如果放前面,那么字符串起始指针和内存块起始不一致怎么解决

Java不存在这个问题,我觉得。元数据和length字段都在实际数组之前呢。Java中,访问任何对象之前都要再多一次跳转,跳过元数据(和length)。

字符串拼接的时候把源串复制到目标串结尾,那么目标串剩余内存不够怎么办,重新分配要多一次赋值,频繁拼接性能有问题怎么办

  • 这个问题比较核心,Java的String不可变设计导致了只能单独复制一份来new String。
  • 这个问题,编译器、JVM很难优化,你把单个的字符串拼接操作优化成StringBuilder的append,但是也扛不住我在for循环中频繁append啊。而且每次new一个StringBuilder也是很大的负担。
  • 当然,也有优化的办法,string相加的时候,string内部持有一个String数组,在展示的时候,才拼成最终的String。但这个改动就比较大了。

要不要设计单独的辅助类来解决字符串拼接问题

那这个辅助类怎么设计,要不要考虑线程安全

如果考虑线程安全的话,怎么兼顾性能

现在看来是要一个辅助类的,比如StringBuilder(非线程安全)和StringBuffer(线程安全),但StringBuilder的线程安全也仅仅是每个方法前面加了synchronized而已啊。

然后说性能,我要append一个长度为1000的String,按理来说String不可变,我可以把String存到数组里,build的时候再拼。

但是StringBuilder的实现还是一个一个char拷进StringBuilder,最后拼的时候,再拷了一次。多copy了一次啊。

说到这儿, @RednaxelaFX 也在回答的评论区提到了:

在Oracle JDK / OpenJDK的实现中,无论用StringBuffer还是StringBuilder去作为字符串拼接的底层实现其实都不是最优的——它们俩都不是为append-only场景优化,而是为更通用的可变字符串场景优化的。

然后我看看如何实现:

List暂存一把最后需要的时候直接造个新string

我先去查了下,Apache Commons和Guava里面居然都没有这个实现,这个让我很吃惊。

但是仔细一想,这个优化第三方库确实很难做:

  • List先转成char[],copy了一次。通过这个char[]来new String的时候,还得再copy一次(String和其他对象共享char[]的构造方法是包级别的,不是public的)
  • 如果要做只能使用反射或者unsafe来强行调用了,这样就和实现绑定了,不通用了。

所以现在看来,String的append操作,确实很难优化。要不将String实现搞复杂;要不上层自己写StringBuilder来做。

参考资料:


以上所述就是小编给大家介绍的《StringBuffer,StringBuilder以及String》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

颠覆式创新:移动互联网时代的生存法则

颠覆式创新:移动互联网时代的生存法则

李善友 / 机械工业出版社 / 2014-12-1 / 69

为什么把每件事情都做对了,仍有可能错失城池?为什么无人可敌的领先企业,却在一夜之间虎落平阳? 短短三年间诺基亚陨落,摩托罗拉区区29亿美元出售给联想,芯片业霸主英特尔在移动芯片领域份额几乎为零,风光无限的巨头转眼成为被颠覆的恐龙,默默无闻的小公司一战成名迅速崛起,令人瞠目结舌的现象几乎都被“颠覆式创新”法则所解释。颠覆式创新教你在新的商业竞争中“换操作系统”而不是“打补丁”,小公司用破坏性思......一起来看看 《颠覆式创新:移动互联网时代的生存法则》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

SHA 加密
SHA 加密

SHA 加密工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具