Java中new String创建对象数量的疑问及答案正确性求证
Java字符串对象创建数量的常见疑问解答
场景1:初始字符串常量池无对应值时,执行String s1 = new String("test");
问题描述
执行这句代码会创建多少个对象?我原本认为是2个:一个在字符串常量池,另一个是new关键字在堆内存中创建的。但看到相关讨论里提到了char[],这是为什么?
解答
咱们把这个问题拆明白:
- 当常量池中没有"test"这个字面量时,代码里的
"test"会先触发在字符串常量池创建1个String对象。 - 然后
new String("test")会在堆内存中创建另1个独立的String对象,这个对象和常量池里的实例是分开的。
至于为什么会提到char[],是因为在JDK 8及以前,String类的内部是用char[]来存储字符内容的:
- 常量池里的
String对象会持有自己的char[]; - 在JDK 6及更早版本中,堆里的
String对象会复制常量池String的char[],这时会多一个char[]对象;而JDK 7及以后,堆里的String会直接引用常量池String的char[],不会额外创建新的char[]。
不过要注意:大多数面试或技术讨论场景中,默认问的是String类型的对象,所以答案是2个。如果把内部的char[]也算作对象,那就要结合JDK版本来看,但通常不会这么要求——除非问题明确说明要统计所有对象。
场景2:初始字符串常量池无对应值时,执行String s1 = "test"; String s2 = new String("test");
问题描述
我认为会创建3个对象:一个是s1对应的常量池对象,第二个是s2因new在堆内存的对象,第三个是s2引用的char[]。请问这个答案是否正确?
准确结论
你的答案不完全准确,咱们分情况说明:
默认统计
String类型对象时:总共创建2个String对象- 第一行
String s1 = "test";:常量池中没有"test",所以在常量池创建1个String对象,s1直接引用它。 - 第二行
String s2 = new String("test");:在堆内存创建1个新的String对象,s2引用这个堆对象。
- 第一行
如果明确要求统计所有对象(包括内部的
char[]):- JDK 6及更早:常量池的
String有1个char[],堆里的String会复制这个char[],所以额外多1个char[],合计是2个String+ 2个char[],共4个对象; - JDK 7及以后:堆里的
String会直接引用常量池String的char[],所以只有1个char[],合计是2个String+ 1个char[],共3个对象。
- JDK 6及更早:常量池的
但要强调:一般面试或常规技术讨论中,默认只统计String类型的对象,所以准确答案是2个String对象。
内容的提问来源于stack exchange,提问作者vishal patel
相关产品推荐
相关产品推荐

