String类内部维护了一个char[]类型的value用来存储字符串,相对来说源码较为简单些。
1.不可变性
String的不可变主要体现在三个方面:
- String类被定义为final类型,不可被继承
- String中的value[]被定义为final
- String中的所有生成新的String的操作底层都调用Array.copy或者System.copy来生成一个新的String对象
2.构造函数
String的有多个构造函数,但以下几个较为特殊
|
|
以上两个是较为特殊的一类构造函数,第一个用一个现成的String来初始化一个新的String对象,构造方法直接将新的String对象的value指向老的value对象。由于String是不可变的,所以这里不需要重新copy一份value的对象。第二个构造方法看似会破坏String类型的不可变性(当参数value变化时String也会变化),但该构造方法并没有声明为public,只允许在包内使用,被声明为public的String(char value[])底层调用的是Array.copy来实现底层数据拷贝的,上述的两个构造函数已经不建议使用
|
|
上面这个构造函数较为典型,很多其他的构造函数都与其类似或者底层调用了该构造函数,入参是一个char数组(byte[]),offset偏移位置及count偏移量。底层调用Arrays.copy函数来进行深度复制。
|
|
上述两个构造函数入参分别是StringBuffer和StringBuilder,底层都是调用Arrays.copyOf,唯一不同的是StringBuffer是线程不安全的,所有调用时需要用synchronized关键字。
3.其他方法
|
|
indexOf和lastIndexOf主要是index和lastIndex函数的底层调用,通读代码会发现底层实现并没有特别牛逼的kmp算法,仍然是一个字符一个字符扫描实现的。其中lastIndexOf还是用了continue startSearchForLastChar;相对来说比较少见。
|
|
replace用于将String对象中的一个字符替换为另一个字符,如果找不到制定的字符则返回本身,如果找到则会另建一个新的String对象返回。