震惊!90%的Java程序员都答不对这道基础题:String s = new String(“abc“)创建了几个对象?

一道经典面试题引发的思考

面试官:“请问String s = new String("abc");这行代码创建了几个对象?”

很多Java开发者会脱口而出:“1个!在堆里创建了一个String对象呗!”

真相并非如此简单,这道题考察的是你对String底层机制的理解,包括**字符串常量池(String Pool)堆内存(Heap)**的关系。

深入分析:到底创建了几个对象?

情况1:如果"abc"在常量池中不存在

String s = new String("abc");
  1. 先在字符串常量池(String Pool)中创建"abc"对象(如果不存在)。
  2. 然后在堆内存(Heap)中创建一个新的String对象,并指向常量池中的"abc"

结论:创建了2个对象(1个在常量池,1个在堆)。

情况2:如果"abc"已经在常量池中存在

String str1 = "abc";  // 先在常量池中创建"abc"
String str2 = new String("abc");  // 只在堆中创建新对象
  1. str1 = "abc" 已经在常量池中创建了"abc"
  2. new String("abc") 不会重复创建常量池对象,但会在堆中创建新的String实例。

结论:创建了1个对象(只在堆中创建)。

JVM内存模型解析

  • 字符串常量池(String Pool):位于方法区(JDK7之前)/ 堆内存(JDK7之后),存储字符串字面量(如"abc")。
  • 堆内存(Heap)new String("abc")会在堆中创建独立的对象,但它的value仍指向常量池中的"abc"

实际开发中的优化建议

  1. 避免滥用new String("xxx")

    • 直接使用String s = "abc"可以复用常量池中的字符串,减少内存开销。
    • new String("abc")会额外在堆中创建对象,通常没必要。
  2. intern()方法的作用

    String s1 = new String("abc").intern();
    String s2 = "abc";
    System.out.println(s1 == s2); // true
    
    • intern()方法会尝试将字符串放入常量池(如果不存在),并返回常量池中的引用。
  3. 大字符串处理优化

    • 如果处理大量字符串,尽量使用StringBuilderStringBuffer,避免频繁创建新对象。

总结

回到最初的面试题:

  • String s = new String("abc") 可能创建1个或2个对象,取决于"abc"是否已经在常量池中。
  • 字符串常量池的存在是为了优化内存,减少重复字符串的存储。
  • 实际开发中,应优先使用字面量赋值(String s = "abc"),而非new String

如果这篇文章对你有帮助,请点赞 + 关注「佩奇的技术笔记」!

你可能感兴趣的:(Java,java,面试,开发语言)