面试题答案
一键面试String的intern方法工作原理
- 字符串常量池:在Java中,存在字符串常量池,用于存储字符串字面量。当代码中出现字符串字面量时,如
String s = "hello";
,JVM会先在字符串常量池中查找是否已有"hello"这个字符串对象。如果有,则直接返回常量池中该对象的引用;如果没有,则在常量池中创建一个新的字符串对象,并返回其引用。 - intern方法作用:
intern
方法是String
类的一个本地方法。当调用str.intern()
时,如果字符串常量池中已经存在一个与str
内容相同(通过equals
方法比较)的字符串对象,则返回常量池中该字符串对象的引用;否则,将str
的内容添加到字符串常量池中,并返回新添加到常量池中的字符串对象的引用。
提升系统性能的场景及举例
- 场景:在处理大量重复字符串的场景下,使用
intern
方法能够显著提升系统性能。例如,在处理日志、文本分析等场景中,如果存在大量相同的字符串内容,使用intern
方法可以减少内存占用。 - 举例:
import java.util.ArrayList;
import java.util.List;
public class InternExample {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
list1.add("hello" + i % 10);
}
List<String> list2 = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
list2.add(("hello" + i % 10).intern());
}
}
}
在上述代码中,list1
存储的是10万个不同的字符串对象(虽然部分内容重复),而list2
通过intern
方法,使得重复内容的字符串在常量池中只有一份,大大减少了内存占用。
潜在风险
- 内存泄漏风险:由于字符串常量池在JVM生命周期内一直存在,如果在程序中大量调用
intern
方法且使用不当,可能会导致常量池内存泄漏。例如,在一个循环中不断调用intern
方法,将大量动态生成且不会被回收的字符串放入常量池,随着时间推移,常量池会占用越来越多的内存。 - 性能问题:调用
intern
方法本身是有一定开销的,因为它需要在常量池中进行查找操作。如果使用场景不当,如字符串重复率不高的情况下使用intern
,不仅无法提升性能,反而会因为intern
方法的查找开销导致性能下降。此外,在高并发环境下,对常量池的访问可能会成为性能瓶颈,因为常量池的操作并非线程安全,可能需要额外的同步机制,这也会影响性能。