intern()方法的核心作用是复用字符串,减少重复对象、节省内存并支持高效引用比较;调用时若常量池已存在等值字符串则返回其引用,否则将当前字符串引用加入池中并返回,JDK7+在堆中直接存引用,避免复制。

intern() 方法的核心作用是复用字符串,减少重复对象,节省内存,并支持高效引用比较。
让相同内容的字符串指向同一个对象
Java 中字符串常量池(String Pool)是一个特殊区域,用于存放字面量字符串(如 "hello")。调用 intern() 时,JVM 会检查池中是否已存在内容相同的字符串:
- 如果存在,直接返回池中那个字符串的引用;
- 如果不存在,就把当前字符串对象的引用加入池中,再返回该引用。
这意味着,即使两个字符串对象最初在堆中不同(比如通过 new String("abc") 创建),只要它们调用了 intern() 且内容一致,最终就可能 == 比较为 true。
适用于频繁出现的字符串场景
当程序中存在大量重复内容的字符串(如解析 JSON 的字段名、日志中的固定标签、配置项键名等),手动调用 intern() 可显著降低内存占用:
- 避免成百上千个内容相同的 String 对象堆积在堆中;
- 后续用 == 判断相等比 equals() 更快(尤其在高频分支判断中)。
注意 JDK 版本差异
行为关键取决于 JVM 版本:
- JDK 6:字符串池在永久代(PermGen),intern() 会把字符串“拷贝”一份进池;
- JDK 7+:字符串池移到堆中,intern() 不复制内容,而是直接在池中存一个指向原堆对象的引用——更省内存,也更符合直觉。
不是所有字符串都适合 intern
滥用反而有害:
- 随机生成、几乎不重复的字符串(如 UUID、时间戳拼接)调用 intern() 会导致池持续膨胀,甚至引发内存泄漏;
- 短生命周期字符串没必要进池;
- 多线程环境下无额外同步开销,但池本身是全局共享的,高频调用仍需关注 GC 压力。










