String为什么要设计成不可变的
不可变的实现
- 从底层实现来看:String类的底层是使用
char[]
(jdk8及之前)、byte[]
数组(jdk9),无论是字符数组还是字节数组,其声明的时候都是使用private final
来修饰的,并且String 类没有提供修改底层数组的方法。
- 从类的声明来看:String类的声明中也使用了
final
来修饰,导致其不能被继承,进而避免了子类破坏的String 不可变。
- 不可变性的体现:
- 当对字符串变量重新赋值时,需要重新指定一个字符串常量的位置进行赋值,不能在原有的位置修改
- 当对现有的字符串进行拼接操作时,需要重新开辟空间保存拼接以后的字符串,不能在原有的位置修改
- 当调用字符串的replace()替换现有的某个字符时,需要重新开辟空间保存修改以后的字符串,不能在原有的位置修改
为什么要这么设计?
- 缓存与性能优化:通过利用字符串常量池技术,多个引用指向内容相等的字符串实例可实现资源共享,有效优化内存使用效率。
- 安全性增强:在参数传递环节,采用直接操作字符串副本的方式,确保了源字符串的完整性和原始性不受外界操作干扰,增强了数据的安全属性。
- 线程安全特性:字符串的不可变性质自然而然地赋予了其线程安全的属性。在多线程环境下,由于字符串值不可被修改,消除了数据竞争的风险,确保了并发访问的一致性与安全性。
- 哈希码缓存优势:得益于不可变性,字符串的哈希值一经计算便恒定不变,这促进了哈希码的高效缓存。在诸如HashMap、HashSet等集合框架中,频繁调用
hashCode
方法时,预先计算并缓存的哈希值能显著提升系统性能。