黑马程序员技术交流社区

标题: 字符串 [打印本页]

作者: 後天__牛永志    时间: 2011-11-17 14:59
标题: 字符串
String st = new String("abc");
st 在内存中有两个对象,一个是"abc",另一个是什么呢,他们在内存中是怎么保存的,能画图分析一下吗
作者: 咪咪    时间: 2011-11-17 15:08
这个问题之前有人问过,你查看下。
作者: 小王同志    时间: 2011-11-17 15:08
本帖最后由 潜王伟 于 2011-11-17 15:18 编辑

我的理解是:
这句代码,创建了两个对象:st和abc
数据类型分为两类,值类型和引用类型。内存分为栈空间和堆空间。
栈空间存放值类型数据和堆空间的引用地址,堆空间则存放引用类型的数据。
string 型是特殊的引用类型,所以这里创建了一个string型的对象,在名为st的栈空间中存放了真正存放“abc”的堆空间地址。
所以是两个。

如有错误,请高手纠正。灰常感谢!
作者: 袁世宇    时间: 2011-11-17 15:15
应该是两个 一个是abc 另一个是st
作者: 骚灵小情歌    时间: 2011-11-17 15:37
本帖最后由 骚灵小情歌 于 2011-11-17 15:38 编辑

图不好贴
String s1 = "abc";
String s2 = new String("abc");

这两句放在一起才能回答你问的问题,单独一条String s2 = new String(abc);何来两个对象???

如上,s1在内存中有一个对象。
         s2在内存中两两个对象。

内存图呢,也就那样,有什么对象就有什么地址的指向.
作者: 小王同志    时间: 2011-11-17 15:50
本帖最后由 潜王伟 于 2011-11-17 15:50 编辑
骚灵小情歌 发表于 2011-11-17 15:37
图不好贴
String s1 = "abc";
String s2 = new String("abc");


楼上的,你看错了,他的代码压根儿就没有什么s1,s2,是st,所以只有一句就是两个对象...
作者: 骚灵小情歌    时间: 2011-11-17 16:06
潜王伟 发表于 2011-11-17 15:50
楼上的,你看错了,他的代码压根儿就没有什么s1,s2,是st,所以只有一句就是两个对象... ...

:dizzy::funk:
作者: 任俊杰    时间: 2011-11-17 16:35
怎么可能这么一句能搞出两个对象来呢。如果是两块存储空间还好理解。一个在堆内存中分了一片内存来保存new String("abc");一个是在栈空间里面分配的一个引用变量来存放new String("abc")这片堆内存的地址。
作者: 小王同志    时间: 2011-11-17 17:01
任俊杰 发表于 2011-11-17 16:35
怎么可能这么一句能搞出两个对象来呢。如果是两块存储空间还好理解。一个在堆内存中分了一片内存来保存new  ...

这是一个很经典的问题了,你可以上网搜一下,应该有很多的文章的...
作者: 任俊杰    时间: 2011-11-17 18:33
使用new创建字符串对象的步骤如下。
1. 首先在堆(不是常量池)中创建一个包含指定内容的字符串对象,并将字符串引用指向该对象。
2. 去字符串常量池中查看,是否有包含该内容的对象。
3. 若有,则将new出来的字符串对象与字符串常量池中内容相同的对象联系起来。
4. 若没有,则在字符串常量池中再创建一个包含该内容的字符串对象,并将堆中的对象与字符串常量池中新创建出来的对象联系起来。
------------
可以通过 public   String   intern() 方法来检测:普通堆中的字符串对象 对应的 字符串常量池中的对象。
public   String   intern() 方法:是将指定字符串对象在字符串常量池中对应对象的引用返回。
---------------
这样做的目的是为了:提高字符串的比较速度。

        字符串特殊的内存机制带来的好处,即是:不管字符串多长,其比较速度都是一样的。因为在比较两个字符串内容是否相同时,不必真去考察内容,只需比较两个字符串联系的常量池中对象是否为同一个即可。这也就将对内容的比较转化为对引用的比较,大大提高了速度。

作者: 任俊杰    时间: 2011-11-17 18:41
看看jdk对该构造方法的说明

未命名.jpg (28.9 KB, 下载次数: 29)

未命名.jpg

作者: xiwangliujiao    时间: 2011-11-17 18:44
本帖最后由 xiwangliujiao 于 2011-11-17 18:52 编辑

两个对象,一个是“abc”,一个是指向“abc”的引用对象
等价于:String  s = "abc";
              String str = new String();
             str = s;
str和String("abc")中的"abc"都在栈中!
而str指向的"abc"在堆中!





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2