String被设计成不可变,核心是为了保障安全、提升性能和简化并发处理;它防止敏感数据被篡改、支撑常量池复用、实现线程安全与哈希缓存,并通过final类、private final字段等机制强制保证。

String 被设计成不可变,核心是为了保障安全、提升性能和简化并发处理。这不是一个随意的设计选择,而是 Java 平台在长期实践中权衡出来的关键约束。
防止敏感数据被意外或恶意篡改
String 大量用于用户名、密码、URL、SQL 查询、系统路径等关键场景。如果它是可变的:
- 方法传参时,调用方传入一个字符串,被调方法内部一修改,原始值就变了,外部逻辑可能直接出错;
- JVM 类加载依赖类名(String 类型),若类名字符串中途被改写,可能导致加载错误的类,引发严重安全漏洞;
- 网络请求头、数据库连接参数等一旦被中间代码篡改,后果难以追溯。
支撑字符串常量池正常工作
Java 用字符串常量池复用相同字面量,节省内存。例如:
String s1 = "hello"; String s2 = "hello"; → 实际指向堆中同一个对象。
如果 String 可变,s1 修改内容就会连带影响 s2,常量池就失去意义,甚至引发数据错乱。不可变性是常量池机制成立的前提。
天然支持线程安全与哈希缓存
不可变意味着对象状态从创建起就固定不变:
- 多线程可自由共享同一 String 实例,无需同步或加锁;
- hashCode 可在构造时计算一次并缓存,后续反复使用不需重算,HashMap 等集合用 String 做 key 时效率更高。
底层实现上做了多重防护
不可变不是靠约定,而是由语言机制强制保证:
- String 类被 final 修饰,无法被继承,杜绝子类破坏封装;
- 内部存储字符的 char[] value 是 private final,既不能被外部访问,也不能重新赋值;
- 所有看似“修改”的方法(如 substring、toUpperCase、replace)都返回新 String 对象,原对象不受影响。

















