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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 程洋 中级黑马   /  2013-12-16 10:01  /  1218 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

在讲到String s="abc";和String s1=newString("abc");说到前者有一个对象,后者有两个对象(一个是new的,一个是"abc")而后面又讲了一个String s2="abc";说是因为内存中已经有了abc这个对象,就不用重建了所以s和s2的内存地址相同;问题就来了s1不是有两个对象吗一个是空字符串(""),另一个是"abc";可不可以说s1同时指向两个内存地址?还是怎么的.

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

7 个回复

倒序浏览
String s1=newString("abc");就拿这个例子来说,
1、首先在堆里面new了一块空间,释放一个“abc”的十六进制出来,
2、然后在栈里面开辟了一个s1空间接收了从堆里面new的“abc”的十六进制,并指向了堆里面的对应new空间

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报

API文档这样解释这个String构造方法
public String(String original):
初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。
由于 String 是不可变的,所以无需使用此构造方法,除非需要 original 的显式副本。

我也不是很懂,查到了这篇文章,你可以参考参考
http://www.iteye.com/topic/774673

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
String不是基本数据类型,是一个特殊的包装类。但是它的对象,也就是"abc"字符串有可能被放在栈内存中,也有可能在堆内存中,具体要看上下文。s是个字符串对象的引用,s和它对应的字符串对象都放在栈内存中。s1引用放在栈内存中,其指向的字符串对象放在堆内存中。s2和它对应的字符串对象都放在栈内存中。因为字符串对象如果在栈内存中,实际上是处于其字符串常量池中,所以栈内存中的字符串对象不会有重复的,s和s2指向同一个字符串常量。s1指向的是堆内存中的字符串对象,不会同时指向两个地址。

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
说一下我个人的理解。有错误希望指出,谢谢。首先,在栈中会有个常量池,String s = " abc",这句话是先在常量池中看有没有“abc”这个对象,如果没有,则在常量池中创建一个“abc”对象。而当String s1 = new String("abc")独立存在时,s1指向堆中的一块内存,叫new String()这个对象,而new String() 指向常量池中的“abc”,所以会创建两个对象。另外,String s2 ="abc",因为在常量池中已经有了“abc”这个对象了,所以不会再创建对象了。这是个人看法。请指教。

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报 1 0
查找了一些东西,不是非常理解:大家参考下
String s=newString("abc");
它就相当于在对内存中开辟了两个空间
一个是"abc"开的
一个是new开的,这个开辟的空间中也装的是"abc"(怎么来的不清楚)
"abc"开的空间没人引用,相当于废的;
而s最终指向的是new出来的这个地址;这是不是就是不建议使用这种方法的原因.
回复 使用道具 举报
Y_Y 中级黑马 2013-12-16 11:20:06
7#
s1不是指向俩个地址String s1=newString("abc");   ”abc“  是放在Stringpool里的    String s1=newString("abc"); 是在堆里里面重新开辟空间  所以他们的地址是不一样的    ”abc“  是放在池里  所以字符串相同  应该地址也是一样的  我是这么理解的!

  一、String 定义:
1、从概念上讲,java字符串就是Unicode字符序列。每个用双引号括起来的字符串都是String类的一个实例。Java字符串由char序列组成,字符数据类型是一个采用UTF-16的编码表示Unicode代码点的代码单元。
2、格式:
01.String a = ”abc”;//存储在StringPool中

02.String b = new String(”abc”)://存储在堆内存中
复制代码3、StringPool(字符串池):有一个存放字符串的公共存储池,称为StringPool,即字符串池。字符变量指向存储池中的相应位置。如果是通过复制一个字符串变量,原始的字符串和复制的字符串将共享这个相同的字符串。

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就创建一个新的对象,它依据那个常量”xyz”对象的内容来创建出一个新String对象。如果以前就用过’xyz’,这句代表就不会创建”xyz”自己了,直接从缓冲区拿。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马