1. 方法核心机制
intern()
方法会在堆内存中创建一个与该字符串对象完全相同的副本,并将其存入字符串常量池。⚠️ 需要注意的是:
- 如果字符串常量池中已存在内容相同的字符串,则直接返回常量池中的引用
- 不会在堆中创建新对象,避免内存浪费
- 本质上是一个空间换时间的优化手段
2. 方法签名
public String intern()
✅ 无参数,返回字符串对象的常量池引用
3. 实战示例
@Test
public void whenIntern_thenCorrect() {
String s1 = "abc"; // 直接指向常量池
String s2 = new String("abc"); // 堆中新对象
String s3 = new String("foo"); // 堆中新对象
String s4 = s1.intern(); // 返回常量池引用
String s5 = s2.intern(); // 返回常量池中已存在的"abc"
assertFalse(s3 == s4); // "foo"与"abc"不同
assertTrue(s1 == s5); // s1和s5都指向常量池中的"abc"
}
关键点解析
s1 vs s2
s1
直接指向常量池中的 "abc"s2
是堆中新创建的对象,内容虽相同但地址不同
intern() 的作用
s2.intern()
发现常量池已有 "abc",直接返回其引用s3.intern()
会将 "foo" 加入常量池并返回新引用
内存对比
变量 存储位置 说明 s1 常量池 字面量直接创建 s2 堆内存 new 关键字创建 s4 常量池 intern() 返回的引用 s5 常量池 与 s1 相同的引用
⚠️ 踩坑提醒:过度使用 intern()
可能导致常量池内存溢出(PermGen/Metaspace OOM),仅在需要严格字符串复用时使用。