MST

星途 面试题库

面试题:Java常量池中的字符串常量的创建与复用机制

当使用 `String s1 = "hello";` 和 `String s2 = new String("hello");` 这两种方式创建字符串时,常量池是如何参与的?它们在内存中的存储有何不同?在什么情况下会出现字符串常量的复用?
26.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 常量池的参与
    • String s1 = "hello";
      • 当执行 String s1 = "hello"; 时,JVM 首先会在字符串常量池中查找是否存在内容为 “hello” 的字符串对象。
      • 如果存在,则直接将 s1 指向常量池中的这个字符串对象。
      • 如果不存在,则在常量池中创建一个内容为 “hello” 的字符串对象,然后将 s1 指向它。
    • String s2 = new String("hello");
      • 首先在字符串常量池中查找是否存在内容为 “hello” 的字符串对象。
      • 如果不存在,会在常量池中创建一个内容为 “hello” 的字符串对象。
      • 无论常量池中是否存在,new String("hello") 都会在堆内存中创建一个新的字符串对象,然后将 s2 指向堆内存中的这个对象。
  2. 内存存储的不同
    • String s1 = "hello";:s1 指向字符串常量池中的对象,只有一个对象(在常量池中)。
    • String s2 = new String("hello");:s2 指向堆内存中的对象,同时常量池中也可能存在(若之前不存在则创建)一个相同内容的对象,即至少有一个堆对象,可能有一个常量池对象。
  3. 字符串常量复用的情况
    • 当使用 String s = "xxx"; 这种方式创建字符串时,如果常量池中已经存在相同内容的字符串对象,就会复用常量池中的对象。例如:
String s1 = "world";
String s2 = "world";
// 这里 s1 和 s2 指向常量池中的同一个 “world” 对象
  • 对于 intern() 方法。如果一个字符串对象调用 intern() 方法,JVM 会在常量池中查找是否存在相同内容的字符串对象。如果存在,则返回常量池中对象的引用;如果不存在,则将该字符串对象添加到常量池中,并返回其引用。例如:
String s3 = new String("java");
String s4 = s3.intern();
// 假设常量池中之前没有 “java”,执行 intern() 后,s4 指向常量池中的 “java” 对象,
// 而 s3 仍然指向堆中的对象