String字符串常量池与intern()方法?
请解释Java中**字符串常量池(String Constant Pool)**的概念,包括存储位置的变化(方法区→堆→元空间)、创建字符串对象的方式(字面量vs new)的区别,以及intern()方法的作用。
回答
我还是少年
字符串常量池:JVM为字符串字面量维护的缓存池,相同内容的字符串字面量共享同一对象。
存储位置变迁:
- Java 6及之前:方法区(永久代)
- Java 7:移到堆中(减少永久代溢出风险)
- Java 8+:仍是堆,永久代被元空间替代(但字符串池仍在堆)
创建方式区别:
String s1 = "hello"; // 字面量:从常量池获取,没有则创建并放入池
String s2 = new String("hello"); // new:在堆中创建新对象,常量池中也可能有
s1 == s2; // false
intern()方法:
- 检查常量池中是否存在equals相等的字符串
- 存在 → 返回常量池中的引用
- 不存在 → 将当前字符串放入常量池,返回引用
String s3 = s2.intern();
s1 == s3; // true(都指向常量池中的同一个对象)
使用场景:减少内存中重复字符串对象的数量(如大量相同值的String)。但intern()本身有性能开销。
注意:Java 7+中,字符串池在堆中,intern()不再有永久代溢出的风险。