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

防止敏感信息被意外或恶意篡改
String在Java中大量用于承载关键路径信息,比如数据库连接URL、文件系统路径、HTTP请求头、用户凭证等。这些内容一旦被修改,可能直接导致越权访问、路径遍历、SQL注入等严重漏洞。不可变性从根源上切断了“拿到引用就等于能改内容”的风险链。例如,一个方法接收密码字符串做校验,如果String可变,调用方或中间拦截代码就可能在验证通过后悄悄替换为其他值;而实际中,任何看似修改的操作(如password.toUpperCase())都只生成新对象,原始密码字符串始终不变。
保障类加载与安全检查机制可信
JVM依赖String精确表示类名、包名、资源路径等元数据。类加载器通过全限定类名查找并加载.class文件,安全管理器也基于字符串判断权限策略(如SecurityManager.checkPackageAccess("java.lang"))。若类名字符串可被运行时修改,攻击者就可能在类加载中途篡改目标类名,绕过双亲委派或沙箱限制,加载恶意字节码。String的不可变确保了类标识符的稳定性和唯一性,是Java安全模型的底层支柱之一。
避免跨上下文参数污染
在Web容器、RPC框架或权限校验逻辑中,字符串常作为上下文传递参数(如用户ID、租户标识、API签名原文)。不可变性保证了参数在调用链中逐层传递时不会被上游或下游模块无意修改。比如Spring Security中认证对象携带的username,或Dubbo中Attachment传递的traceId,都不必担心被中间过滤器或日志组件意外覆盖——所有“修改”只是创建新副本,原值始终受控。
消除共享引用引发的安全歧义
字符串常量池使多个变量可能指向同一String实例(如String a = "admin"; String b = "admin"结果为a == b)。若String可变,一个模块修改a的内容,会静默影响所有共享该实例的模块,造成行为不一致甚至权限错乱。不可变性让这种共享变为安全复用:既节省内存,又杜绝副作用。这也是为什么Java允许字符串字面量直接用于switch语句和注解属性——编译期和运行期都能确信其值恒定。
立即学习“Java免费学习笔记(深入)”;


















