四个主要原因:1)字符串常量池的前提——只有不可变,字面量 intern 共享才安全,否则一个引用改了值会污染所有共享者;2)hashCode 可缓存——String 的 hash 只算一次并缓存,这是它能高效做 HashMap key 的关键;若可变,改值后 hash 变化,放进 HashMap 的键会「丢失」;3)线程安全——不可变对象天然线程安全,多线程共享无需同步;4)安全性——文件路径、URL、类加载的类名、网络连接参数都以 String 传递,若可被篡改,校验通过后内容被改将造成严重漏洞。

代价与配套:频繁拼接产生大量中间对象,所以有了 StringBuilder/StringBuffer,以及编译器把字面量拼接优化为 builder 链。追问方向:String 真的是绝对不可变吗(反射可以改 value 数组,Java 9 后字段变 byte[] 且模块封装加强了防护)、不可变与防御性拷贝的关系(构造器里对传入数组要拷贝)、Java 9 的 Compact Strings(Latin-1 用单字节存储)。

(约 360 字)