String类是不可变类,一个String对象被创建以后,包含这个对象中的字符串序列是不可改变的。
什么是不可变对象? 如果一个对象它被创建后,状态不能改变,则这个对象被认为是不可变的。
设计不可变原因
总结来说,不可变的String对象在并发环境下更安全、更高效,提供了更好的性能和安全性,同时利用字符串池可以节省内存。因此,String被设计成不可变的。Java 字符串设计成不可变的主要目的是为了安全和高效。这使得字符串在实际应用中更加可靠和高效。
线程安全
不可变的String对象可以被多个线程安全地共享,因为它们的值是在创建时确定的,不会改变。这样就避免了多线程环境下的并发访问和修改带来的竞争问题。
从同步角度来说,字符串的不可变性使得其天生就是线程安全的,不需要任何同步处理。字符串的不可变性还使得其在多线程环境中具有优势。因为不可变对象不能被改变,所以他们可以自由地在多个线程之间共享,不需要任何同步处理
缓存哈希值
String的哈希值在创建时被计算出来,并且被缓存起来。这样,在后续的操作中,如果发现String的哈希值已经被缓存,就不需要重新计算了,可以直接使用缓存的值。这样可以提高哈希表等数据结构的性能。
String 对象可以缓存 hashCode。字符串的不可变性保证了 hash 码的唯一性,因此可以缓存 String 的 hashCode,这样不用每次去重新计算哈希码。在进行字符串比较时,可以直接比较 hashCode,提高了比较性能。
从数据结构角度来说,字符串的不可变性使得其哈希码保持一致,避免了不必要的麻烦。在 Java 中,字符串的不可变性还使得其哈希码保持一致。这是因为哈希码是根据字符串的内容计算的,如果字符串可以被修改,那么其哈希码也将改变,从而导致一些不必要的麻烦。
安全性
不可变的String对象可以在网络传输、文件读写等场景下提供更高的安全性。例如,如果String对象的内容被修改,那么在传输过程中可能会被篡改,而不可变的String对象可以确保它的内容在传输过程中不会被修改。
String 被许多 java 类用来当作参数,如 url 地址,文件 path 路径,反射机制所需的 Strign 参数等,若 String 可变,将会引起各种安全隐患。
字符串池
Java中的字符串池(String Pool)是一块预分配的内存区域,用于存储字符串常量。不可变的String对象可以在字符串池中被共享使用,这样可以减少内存的使用,提高性能。
字符串常量池需要 String 不可变。因为 String 设计成不可变,当创建一个 String 对象时,若此字符串值已经存在于常量池中,则不会创建一个新的对象,而是引用已经存在的对象。如果字符串变量允许必变,会导致各种逻辑错误,如改变一个对象会影响到另一个独立对象。
从内存角度来说,字符串池的存在使得字符串的重复创建可以被避免,从而节省内存空间。