java中string不可变指对象内容不可修改,而非变量不能重新赋值;其设计支撑常量池复用、线程安全、哈希值缓存及系统安全性,频繁拼接应使用stringbuilder或stringbuffer优化。

Java 中 String 类型的变量“不可变”,不是指变量本身不能重新赋值,而是指它所指向的字符串对象内容一旦创建就无法被修改。
String 对象的内容在内存中不可更改
当你写 String s = "hello";,JVM 在字符串常量池中创建一个内容为 "hello" 的 String 对象。之后执行 s = s + " world";,并不会把原对象改成 "hello world",而是新建一个字符串对象 "hello world",让 s 指向它——原来的 "hello" 对象仍留在内存中(除非无引用被回收)。
- 所有 String 的修改操作(如
substring()、toUpperCase()、replace())都返回新对象,原对象不变 - String 内部用
final char[](Java 8 及以前)或final byte[](Java 9+)存储字符,且数组本身不可替换、不可扩容 - String 类自身被声明为
final,不能被继承,防止子类破坏不可变契约
变量可变,对象不可变——别混淆两者
声明 String s = "a"; s = "b"; 是完全合法的:这里的 s 是引用变量,可以指向不同对象;但 "a" 和 "b" 这两个对象各自的内容从诞生起就固定了。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 类似给房间换门牌号——门牌(变量)能换,但房间内部陈设(对象内容)不能动
-
final String s = "x";表示 s 引用不可再指向其他对象,进一步强化“不可变引用”,但这和 String 类本身的不可变性是两回事
为什么设计成不可变?关键好处有哪些
不可变性不是限制,而是为安全与性能做的深思熟虑:
- 线程安全:多个线程共享同一个 String 实例,无需同步,不会出现读到中间状态的问题
-
字符串常量池优化:因为内容确定不变,JVM 才敢放心复用相同字面量的对象(如
"abc"多次出现只存一份) -
缓存哈希值:String 重写了
hashCode(),首次调用后结果被缓存(内部有hash字段),后续直接返回,提升 HashMap 等集合性能 - 安全性:作为类加载器、网络请求参数、文件路径等关键场景的输入,不可变可防止被意外或恶意篡改
需要频繁修改文本时该怎么做
如果业务逻辑涉及大量拼接、插入、删除(比如构建 SQL 或日志),直接用 String 会产生大量临时对象,影响性能。
- 优先使用
StringBuilder(单线程场景)或StringBuffer(多线程需同步) - 它们底层用可变的
char[],append、delete、insert 等操作都在原数组上进行,不创建新对象 - 最后用
.toString()获得一个不可变 String 用于后续不可变语义的场景
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










