字符串常量池通过安全复用减少重复对象,降低内存占用并提升引用比较效率;字面量自动入池,new String() 造成冗余堆对象;intern() 适用于高重复、长生命周期字符串,但需避免滥用引发性能问题。

Java 中字符串常量池的核心作用不是“主动压缩”,而是通过安全复用减少重复对象数量,从而降低内存占用、提升引用比较效率。它依赖 String 的不可变性,让 JVM 敢于共享同一份内容的多个引用。
字面量自动入池,避免无谓堆分配
双引号定义的字符串(如 "GET"、"200"、"active")在类加载阶段就进入常量池,后续相同字面量直接复用同一个对象引用。
- ✅ 推荐写法:
String method = "POST";→ 全局只有一份,栈上变量指向池中唯一实例 - ❌ 避免写法:
String method = new String("POST");→ 每次都在堆新建对象,value 字段仍指向池中字符数组,但对象本身冗余 - ⚠️ 注意:
"POST".intern()对已存在的字面量无效,纯属多余调用
运行期高重复字符串可谨慎 intern()
从数据库、配置中心或网络读取的字符串,若内容重复率高、生命周期长(如状态码、币种、协议字段),适合显式调用 intern() 归一化。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 典型适用:
"SUCCESS"、"PENDING"、"USD"、"v2" - 操作示例:
String status = resultSet.getString("status").intern(); - 效果:10 万条记录中若有 9 万个
"SUCCESS",经intern()后仅保留 1 个对象,而非 9 万个独立堆实例
JDK 9+ 紧凑字符串自动节省空间
无需代码改动,JVM 自动启用:当字符串内容全为 Latin-1 字符(ASCII 0–127,如英文、数字、常见符号),内部改用 byte[] 存储,每个字符占 1 字节,相比旧版 char[](2 字节)节省约 50% 内存。
立即学习“Java免费学习笔记(深入)”;
- 生效条件:字符串所有字符的 Unicode 值 ≤ 127
- 完全透明:
length()、charAt()、substring()等行为不变 - 验证方式:可用 JOL(Java Object Layout)工具查看实际内存布局
慎用 intern():它不是缓存万能键
intern() 是全局同步操作,底层哈希表查表+加锁,滥用会引发性能瓶颈和内存风险。
- ❌ 禁止对唯一值调用:UUID、时间戳、随机 token —— 几乎不重复,
intern()后白占空间且难回收 - ❌ 避免循环内无条件调用:
for (String s : list) { s.intern(); }→ 每次都触发哈希查找与锁竞争 - ✅ 更可控替代:对明确高频字段,用
ConcurrentHashMap<string string></string>自建缓存,支持大小限制与 LRU 淘汰

















