Java String 的不可变性依赖构造时的安全拷贝实现,即通过 Arrays.copyOf() 复制传入的 char[] 或 byte[] 数组,避免共享引用,确保外部修改不影响字符串内容。

Java String 的不可变性不是靠“不能改”这句话撑起来的,而是靠构造方法里一次关键动作——安全拷贝(defensive copy)真正落地的。
构造时绝不共享原始数组
当你用 new String(char[] value) 或 new String(byte[] value) 创建字符串时,String 源码不会直接把传进来的数组赋给自己的 value 字段。它调用 Arrays.copyOf() 或 Arrays.copyOfRange(),新建一块内存,把原数组内容逐字节复制进去。
- 哪怕你传入一个外部可变的 char 数组,后续改它,对已创建的 String 完全没影响
- 这个复制是“值复制”,不是“引用复制”,切断了外部篡改的通道
- JDK 9+ 改用
byte[]存储,逻辑不变:照样拷贝,照样隔离
为什么不用 this.value = value?
如果构造器写成 this.value = value;,就等于把外部数组的引用直接交出去了。别人拿到那个原始数组,一改,String 内容就“被动变了”——这直接击穿不可变性底线。
- 比如:你传了个
char[] arr = {'a', 'b'};给 String 构造器,之后执行arr[0] = 'z'; - 若没拷贝,String 对象里第一个字符就变成 'z';有拷贝,它还是 'a'
- 这种风险在多线程或敏感数据场景下尤其致命
安全拷贝是防线,不是装饰
它和 final class、private final value、无修改方法一起,构成四道硬约束。单独看任何一条都防不住,但合起来,让 String 从诞生那一刻起,内容就锁死在自己的内存里,谁也碰不着、改不了。
立即学习“Java免费学习笔记(深入)”;
这不是性能妥协,是设计契约:String 就是数据的终点,不是中转站。


















