面试官:“请问String s = new String("abc");
这行代码创建了几个对象?”
很多Java开发者会脱口而出:“1个!在堆里创建了一个String
对象呗!”
但真相并非如此简单,这道题考察的是你对String
底层机制的理解,包括**字符串常量池(String Pool)和堆内存(Heap)**的关系。
"abc"
在常量池中不存在String s = new String("abc");
"abc"
对象(如果不存在)。String
对象,并指向常量池中的"abc"
。结论:创建了2个对象(1个在常量池,1个在堆)。
"abc"
已经在常量池中存在String str1 = "abc"; // 先在常量池中创建"abc"
String str2 = new String("abc"); // 只在堆中创建新对象
str1 = "abc"
已经在常量池中创建了"abc"
。new String("abc")
不会重复创建常量池对象,但会在堆中创建新的String
实例。结论:创建了1个对象(只在堆中创建)。
"abc"
)。new String("abc")
会在堆中创建独立的对象,但它的value
仍指向常量池中的"abc"
。避免滥用new String("xxx")
String s = "abc"
可以复用常量池中的字符串,减少内存开销。new String("abc")
会额外在堆中创建对象,通常没必要。intern()
方法的作用
String s1 = new String("abc").intern();
String s2 = "abc";
System.out.println(s1 == s2); // true
intern()
方法会尝试将字符串放入常量池(如果不存在),并返回常量池中的引用。大字符串处理优化
StringBuilder
或StringBuffer
,避免频繁创建新对象。回到最初的面试题:
String s = new String("abc")
可能创建1个或2个对象,取决于"abc"
是否已经在常量池中。String s = "abc"
),而非new String
。如果这篇文章对你有帮助,请点赞 + 关注「佩奇的技术笔记」!