java源码笔记之String

来源:互联网 发布:python 运算符 编辑:程序博客网 时间:2024/06/17 10:30

        

String不是一个基本类型,而是一个final class,它的主体是由一个char数组组成,而这个char数组和其它的field都是final的,因此是不允许改变的。这种设计有其使用的好处,比如可以当单例对象来共享数据等;但是同样在一些场景中也会带来不便,比如说当你想在一个字符串后加上一个字符串时。主要是因为当你要往一个字符串后加上一段字符串时,字符串并不是去改变char数组,增大其容量,然后将要加的字符串append到该数组后面去,而是重新创建了一个字符串,然后将二者之和赋值给了新的字符串来返回给调用者。

这样的相加方式,在大规模的操作下会创建大量的对象,从而会有性能问题。因此为了解决这种情况,jdk中引入了stringbuffer。stringbuffer与string的一大不同是其数据结构的char[]是可变的,而且它在这个数据的拷贝中使用了目前java中最快的数组拷贝方式-system.arraycopy()。该函数调用了一个jni函数,采用的是内存的拷贝。

而stringbuffer中的大多数该数组上的变更操作都是加锁的,以保证线程安全。但是线程安全也意味着性能上的消耗,因此为了在单线程的情况下节省这些不必要的性能消耗,后在jdk5.0后加入stringbuilder,与stringbuffer继承自同一父类,唯一区别是去掉了锁,从而不能保证线程安全。

因此,在字符串使用上,在大规模字符串串联的情况下,如果要保证线程安全则使用stringbuffer,如果只在单线程的情况下,则可以采用stringbuilder来得到最好的效率,不必不味地使用stirngbuffer。

string另外一个不得不提的是,当使用string str="abc"来创建字符串时,jvm是先从字符串常量池中找有没有同样的值,有的话就不会去再new一个对象,而是直接将该常量值中的引用赋值给它。也可以手动使用intern()函数将一个字符串的值注册到常量池中。

原创粉丝点击