A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 贠(yun)靖 于 2012-3-16 19:05 编辑

  如题  String s=new String("abc")创建两个对象,一个在堆里,另外一个在那?  
         我知道字符串  存储还有个地方就是在 常量池  如果另外一个字符串在常量池的话   那么是不是就没有引用对象指向它?
      而  这个 s 应该是指向堆内存中的这个对象吧?

8 个回复

倒序浏览
数据区,共享区,名字很多,就是静态所在的区了
回复 使用道具 举报
字符串有一个常量池,好像,
回复 使用道具 举报
“abc”这个对象在常量池,new String()在堆里
回复 使用道具 举报
额,前辈。我是这么认为的
我们在使用String s=new String();创建一个字符串对象,首先它在栈内存中就有了一个字符串类型的引用s,并且我们假设它在堆内存中分配的地址是12345;"abc"本身就是一个对象了,当我们传入了一个字符串"abc"作为参数传给了对象s,
那么s就会先在内存中常量池,字符串常量池去找这个abc对象。abc在常量池中是有地址的,比如说是12344,(本来直接可以用s指向常量池中abc的,但是我们new了一下他就有了新的地址12345,也就是我们创建了一个新的对象)
当它作为了参数传给了一个新的字符串对象s,那么s就拿着12344这个地址找到了了abc对象,然后jvm就照着abc的摸样又造了一个abc给了s。我通过这12344和12345这两个地址都可以找到abc这个对象,但却不是一个对象了。
(注意,这里并没有把abc以前的地址值给覆盖掉,)
举个实际中的例子吧:比如说一个富翁,他有一套别墅叫白宫,在xxx区。然后他就又想在yyy区建造一个一模一样的别墅也叫白宫。也就是说这个富翁就是你,你本来在常量池中有了一个别墅,后来又在新的地址上建造了一个一模一样的别墅。你通过xxx可以找到白宫,你通过yyy也可以找到白宫!

{:soso_e128:}请笑纳呀!

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1

查看全部评分

回复 使用道具 举报

RE: String s=new String(

张润政 发表于 2012-3-16 19:39
额,前辈。我是这么认为的
我们在使用String s=new String();创建一个字符串对象,首先它在栈内存中就有了 ...

哦了,谢谢啦,我那是前辈~承受不起啊!
回复 使用道具 举报


画张图给你看看吧!

评分

参与人数 1技术分 +1 收起 理由
房宝彬 + 1 很好,但是很不全面哦,

查看全部评分

回复 使用道具 举报
String s=new String("abc")
String本身就是一个类,而一个字符串就是String类的匿名对象,如果使用了new关键字,那么无论如何都会重新开辟一个空间而这个空间的内容还是"abc"
之后另外一个“abc”就成垃圾了
加入用 String s="abc"  那么内存中始终只有一份abc 当重新再定义 String r="abc" 时 r和s 指向的是同一个内存空间
可以用这样的代码来验证

String s="abc" ;
String r="abc" ;
String b=new String("abc")

System.out.println(s==r);
结果返回的是true
System.out.println(s==b);
结果返回的false

则可以验证我上面所说的了
回复 使用道具 举报
创建的字符abc在堆内存,s在栈内存,new s 后,又在对内存中创建了一个abc给s,abc有一个物理地址,其实是s借助abc的地址找到的。对内存中有两个abc;但是java中有一个垃圾清理机制,系统会自动清理没有指向的数据……
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马