String为什么要设计成不可变的

36 阅读2分钟

不可变的实现

  1. 从底层实现来看:String类的底层是使用char[](jdk8及之前)、byte[]数组(jdk9),无论是字符数组还是字节数组,其声明的时候都是使用private final来修饰的,并且String 类没有提供修改底层数组的方法。
  2. 从类的声明来看:String类的声明中也使用了final来修饰,导致其不能被继承,进而避免了子类破坏的String 不可变。
  3. 不可变性的体现:
    1. 当对字符串变量重新赋值时,需要重新指定一个字符串常量的位置进行赋值,不能在原有的位置修改
    2. 当对现有的字符串进行拼接操作时,需要重新开辟空间保存拼接以后的字符串,不能在原有的位置修改
    3. 当调用字符串的replace()替换现有的某个字符时,需要重新开辟空间保存修改以后的字符串,不能在原有的位置修改

为什么要这么设计?

  1. 缓存与性能优化:通过利用字符串常量池技术,多个引用指向内容相等的字符串实例可实现资源共享,有效优化内存使用效率。
  2. 安全性增强:在参数传递环节,采用直接操作字符串副本的方式,确保了源字符串的完整性和原始性不受外界操作干扰,增强了数据的安全属性。
  3. 线程安全特性:字符串的不可变性质自然而然地赋予了其线程安全的属性。在多线程环境下,由于字符串值不可被修改,消除了数据竞争的风险,确保了并发访问的一致性与安全性。
  4. 哈希码缓存优势:得益于不可变性,字符串的哈希值一经计算便恒定不变,这促进了哈希码的高效缓存。在诸如HashMap、HashSet等集合框架中,频繁调用hashCode方法时,预先计算并缓存的哈希值能显著提升系统性能。