黑马程序员技术交流社区

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

作者: 惠晖    时间: 2012-11-17 13:06
标题: String字符串
本帖最后由 惠晖 于 2012-11-19 18:35 编辑

String s="abc"; 是一个对象
String s= new String ("abc");是2个对象    这个不太理解啊  怎么是2个对象的呢?,是哪2个对象??????
Java运行环境有一个字符串池,由String类维护。执行语句String s="abc"时,首先查看字符串池中是否存在字符串"abc",如果存在则直接将"abc"赋给s,如果不存在则先在字符串池中新建一个字符串

"abc",然后再将其赋给s。
执行语句String s=new String("abc")时,不管字符串池中是否存在字

符串"abc",直接新建一个字符串"abc"(注意:新建的字符串"abc"不是在字符串池中),然后将其付给s。
前一语句的效率高,后一语句的效率低,因为新建字符串占用内存空间。这是百度的解释  但是我也没看出怎么是2个对象。。。 意思是String "s" ="abc"   s 是一个对象?  abc不是对象?                    String s =new String("abc")s是一个对象 。然后new出来的abc也是一个对象? 是这个意思么
还有字符串池是在堆堆内存中 还是栈内存   还是在其他说明位置?

作者: 崔利鹏    时间: 2012-11-17 13:14
abc这个是新创建了一个对象,但是s是一个引用本身也是一个对象。
作者: 初艳春    时间: 2012-11-17 13:21
String s="abc"; 是一个对象在内存中声明的;
String s= new String ("abc"); 就是不管内存里是不是已经有"abc"这个对象,都新建一个对象保存"abc",是在堆里面建立的对象 String;
作者: 惠晖    时间: 2012-11-17 13:32
星星 发表于 2012-11-17 13:21
String s="abc"; 是一个对象在内存中声明的;
String s= new String ("abc"); 就是不管内存里是不是已经有" ...

能用图像来说明下么 还是不太清楚
作者: 高任    时间: 2012-11-17 13:35
面这行代码分成String s、=、"abc"和newString()四部分来看待。String s只是定义了一个名为str的String类型的变量,因此它并没有创建对象;=是对变量s进行初始化,将某个对象的引用赋值给它,显然也没有创建对象;现在只剩下newString("abc")那么newString("abc")能被看成"abc”和new String() ;s是个类类型变量是一个引用本身指向对象newString();所以是两个对象。
作者: 初艳春    时间: 2012-11-17 13:42
惠晖 发表于 2012-11-17 13:32
能用图像来说明下么 还是不太清楚

所有执行都在内存中,new()一个对象是 new ()创建一个对象(当然会开辟一个内存空间存放在堆里);我也不大会画图,据体的看看教程和课本。
作者: 陈龙    时间: 2012-11-17 13:45
String str = new Sring("hello");

其内存分布如下图,首先是匿名对象"hello"会开辟一个堆内存空间,new也会开辟一个堆内存空间,这两个内存空间的内容是一样,都是"hello"

作者: 惠晖    时间: 2012-11-17 14:05
陈龙 发表于 2012-11-17 13:45
String str = new Sring("hello");

其内存分布如下图,首先是匿名对象"hello"会开辟一个堆内存空间,new也 ...

匿名又从哪里来的啊??
作者: 惠晖    时间: 2012-11-17 14:10
gaoren1033 发表于 2012-11-17 13:35
面这行代码分成String s、=、"abc"和newString()四部分来看待。String s只是定义了一个名为str的String类型 ...

你的解答还是没理解啊 能通俗易懂点么。。。
作者: 王阳    时间: 2012-11-17 17:09
字符串池应该在堆中保存,只不过比较特殊,堆内存中其他的对象,如果没有引用指向了的话,就有可能随时被垃圾处理机制清除,但是字符串池不会,他会一直保存着。
至于String s ="ABC"; String s = new String("abc"); s代表的是一个String的引用, 而=号后面的则代表指向的是,一个指向字符串池的对象,一个指向了堆中的对象,当使用 String s ="abc"时候,.如果字符池没有,则会在堆内存中创建一个然后在字符串池复制一份,并指向进去,但是String s = new String("abc");则是不管字符串池里有没有都会在堆中重新创建一个对象,然后把地址指向s引用。
作者: ssx0101    时间: 2012-11-17 17:30
楼主的猜想是对的。
String s="abc",会在栈内新建一个变量对象s,s是对象。而“abc”在字符串池中检索或者新建,“abc”不是对象,一共有1个对象;
String s=new String("abc"),会在栈内新建一个变量对象s,是对象。会在堆内新建一个对象“abc”,abc是对象,一共有两个对象。
作者: 凊係柈泩    时间: 2012-11-17 17:40
String s=new String("abc")
String本身就是一个类,而一个字符串就是String类的匿名对象,如果使用了new关键字,那么会在堆内存中创建String类并对其初始化值为abc,
s就会指向该地址值。
用 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
作者: 潘天功    时间: 2012-11-18 12:29
String s = new String("abc")之所以是创建两个对象是因为凡是使用new 就表示创建一个对象,而“abc”本身就是一个对象(字符串类型的对象),这个“abc”是作为使用new创建的对象的内存传递过去的。
这就是之所以是两个对象的原因。




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