一、String
1、String类的特性
①、String类被final修饰,不能被继承;
②、String底层是通过char类型的数据实现的,并且被final修饰,所以字符串的值创建之后就不可以被修改,具有不可变性;
③、String实现了Serializable和Comparable接口,表示String支持序列化和可以比较大小。
2、String的实例化
①、通过字面量直接进行实例化
String str = "666";
②、通过new+构造器的方式实例化
String str = new String("666");
3、String类的不可变性
通过字面量方式为字符串赋值时,此时的字符串存储在方法区的字符串常量池中,并且在字符串常量池中不会存储相同内容的字符串。所以String字符串具有不可变性,当字符串重新赋值时,不会在原来的内存地址进行修改,而是重新分配新的内存地址进行赋值。当字符串进行拼接或者调用String的replace方法修改指定的字符或字符串时,也不会在原来的内存地址进行修改,而是重新分配新的内存地址进行赋值。
二、StringBuilder和StringBuffer
StringBuffer、StringBuilder和String类似,底层也是用一个数组来存储字符串的值,并且数组的默认长度为16,即一个空的StringBuffer对象数组长度为16。实例化一个StringBuffer对象即创建了一个大小为16个字符的字符串缓冲区。但是当我们调用有参构造函数创建一个StringBuffer对象时,数组长度就不再是16了,而是根据当前对象的值来决定数组的长度,数组的长度为“当前对象的值的长+16”。所以一个 StringBuffer 创建完成之后,有16个字符的空间可以对其值进行修改。如果修改的值范围超出了16个字符,会先检查StringBuffer对象的原char数组的容量能不能装下新的字符串,如果装不下则会对 char 数组进行扩容。
三、String、StringBuffer和StringBuilder的区别
1、String对象一旦创建,其值是不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象;而StringBuffer和StringBuilder对象的值是可以被修改的。
2、String对象的不可变性使其在多线程环境下是线性安全的,不需要额外的同步措施。StringBuffer几乎所有的方法都使用synchronized实现了同步,线程比较安全,在多线程系统中可以保证数据同步,但是效率比较低;而StringBuilder 没有实现同步,线程不安全,在多线程系统中不能使用 StringBuilder,但是效率比较高。
3、如果我们在实际开发过程中需要对字符串进行频繁的修改,不要使用String,否则会造成内存空间的浪费;当需要考虑线程安全的场景下使用 StringBuffer,如果不需要考虑线程安全,追求效率的场景下可以使用 StringBuilder。