java字符串对象分配问题

来源:6-11 Java内存模型之 常考题解析-1

hellocp7

2019-07-23

老师你好,我想问的是,在jdk1.7之后,也就是把字符串常量池放到了堆中之后。是否所有的新建一个之前没有的字符串的操作,都是先在堆上新建这个对象,然后把该字符串的引用复制到字符串常量池中?因为我看到你说intern方法在jdk1.6之后会顺着 字符串常量池,堆去找,直到堆中没有找到,再在常量池中新建一个字符串对象,返回引用,但是这样的话,堆中何时才会加入这个字符串对象?所以觉得是否应该是在堆中没有找到的话,先在堆中新建,后把对象引用复制一份去常量池,在返回这个引用。

写回答

2回答

JaggerChen

2019-07-23

1、新建一个之前没有的字符串分两种情况:

(1)String str = new String("n") + new String("ew");

在堆中创建这个 String 对象并返回引用。字符串常量池中有 "n" 和 "ew"。

(2)String str = "new";

在字符串常量池中添加 "new" 并返回引用。

2、什么时候把(堆中)该字符串(对象)的引用添加到字符串常量池中?

调用 intern() 方法,前提条件是该字符串对象已经存在于 Java 堆中。

3、堆中何时才会加入这个字符串对象?

为什么一定要在堆中加入这个字符串对象呢?把他们都放在字符串常量池不好吗?

字符串常量池的目的就是为了使字符串能够被复用,节省内存消耗。

相比较 String str = "new",String str = new String("new") 是不推荐的做法。


2
2
hellocp7
真的非常感谢。 那也就是说当我们调用String a = new String("xx")的时候,会同时在常量池和堆中新建一个字符串对象,他们的值一样,但引用的地址不同,同时,在下一次我使用到字符串值是"xx"的时候,他会先去检查常量池是否有值是"xx"的字符串对象,如果有就返回这个对象。如果没有,再去堆中找?
2019-07-24
共2条回复

翔仔

2019-07-23

同学好,比如说 String a = "1",如果常量池中没有1就会先在常量池中创建一个1,同样的情况可以类比到 String a  =  new String("1"),此时也会在常量池中创建一个1,但是会在堆中也创建一个1,并赋值给a,而此时常量池中的1 并不等于a的1.比如

public static void main(String[] args){
    String b = new String("1");
    b.intern();
    String a = "1";
    System.out.println(a == b);
}

 最终结果会返回false

1
3
hellocp7
回复
翔仔
好的。谢谢老师
2019-07-25
共3条回复

剑指Java面试-Offer直通车 百度资深面试官授课

招聘季即将到来,让百度资深面试官来为你的高薪Offer保驾护航

8427 学习 · 1870 问题

查看课程