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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张晴 黑马帝   /  2011-7-21 13:39  /  2304 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

String str1="a";
String str2="b";
String str3="a"+"b";
String str4=str1+"b";
System.out.println(str3=="ab");//true
System.out.println(str4=="ab");//false
如果缓冲池里面原先有"ab",则直接让str4指向就行了,如果没有则由缓冲池里面的字符串"a"和字符串"b",连接生成的一个新字符串,然后再让str4指向,当然原先的"a" ,"b"没变,不论哪种情况,都可以确定str4=="ab"
从结果看str3应是指向堆内存的对象"ab",而对于str3,实际上str3=new StringBuider("str1")+"b"; 这样就能确定生成的对象"ab"是存于堆里面的吗?即str3指向的是堆里面的对象吗?

4 个回复

倒序浏览
黑马网友  发表于 2011-7-21 13:42:06
沙发

笔误,写错了,改后:

String str1="a";
String str2="b";
String str3="a"+"b";
String str4=str1+"b";
System.out.println(str3=="ab");//true
System.out.println(str4=="ab");//false
如果缓冲池里面原先有"ab",则直接让str3指向就行了,如果没有则由缓冲池里面的字符串"a"和字符串"b",连接生成的一个新字符串,然后再让str3指向,当然原先的"a" ,"b"没变,不论哪种情况,都可以确定str3=="ab"
从结果看str4应是指向堆内存的对象"ab",而对于str4,实际上str4=new StringBuider("str1")+"b"; 这样就能确定生成的对象"ab"是存于堆里面的吗?即str4指向的是堆里面的对象吗?
回复 使用道具 举报
黑马网友  发表于 2011-7-21 14:14:50
藤椅
首先说明一下:str3=“a”+"b";
str3为"ab"是在class文件中确定的,即编译以后str3便确定啦。
而str4=str1+“b”;
str4是在运行期间确定的。即首先jvm将str1包装成StrngBuilder("a")对象,然后调用append("b");最后再调用toString()方法,从而得到str4的String对象。也就是str4指向的堆中的String对象。
回复 使用道具 举报

String比较深入的解析

晴儿,认识一下,我叫阿俊。
我看了你的代码解释,发现你对String理解的不够透彻,希望我的回答能为你解惑,当然啦,如果还有疑问,我会为你释疑的(实话说,在回答你问题前,我也有不解,但通过网上学习后,明白了不少,交流学习,效果不错)。

清晰的学习String需具备的知识:
1.内存栈与堆
详细知识请看我回答的内容:http://bbs.itheima.com/thread-360-1-1.html
2.String的关键知识点
String是常量,其对象一旦创建完毕就无法改变。当使用+拼接字符串时,会生成新的String对象,而不是向原有的String对象追加内容。
String Pool(字符串池)——内存栈——即你上面说的缓冲池

String s = “aaa”;(采用字面值方式赋值)
1) 查找String Pool中是否存在“aaa”这个对象,如果不存在,则在String Pool中创建一个“aaa”对象,然后将String Pool中的这个“aaa”对象的地址返回来,赋给引用变量s,这样s会指向String Pool中的这个“aaa”字符串对象
2) 如果存在,则不创建任何对象,直接将String Pool中的这个“aaa”对象地址返回来,赋给s引用。

String s = new String(“aaa”);       ——堆内存
1) 首先在String Pool中查找有没有“aaa”这个字符串对象,如果有,则不在String Pool中再去创建“aaa”这个对象了,直接在堆中(heap)中创建一个“aaa”字符串对象,然后将堆中的这个“aaa”对象的地址返回来,赋给s引用,导致s指向了堆中创建的这个“aaa”字符串对象。
2) 如果没有,则首先在String Pool中创建一个“aaa“对象,然后再在堆中(heap)创建一个”aaa“对象,然后将堆中的这个”aaa“对象的地址返回来,赋给s引用,导致s指向了堆中所创建的这个”aaa“对象。
[code=java]               
String str1="a";   
//检查字符串池String pool 是否有字符串对象"a",如果有,则返回这个对象在栈内存的地址赋值给引用str1;如果没有,则创建一个"a"对象,它所在的栈内存地址返回,并赋值给引用str1。
String str1_1 = "a";
// 当程序执行到这里时,String pool 已经有 对象"a"了,所以不会在创建字符串对象"a",而是直接把String pool中"a"对象的地址返回,赋值给str1_1.所以str1== str1_1 为true。
String str2="b";
String str3="a"+"b";   
// "+"符合是字符串连接符,作用是把两个字符串连接起来,创建一个新的字符串对象"ab",这个是编译时的运算,编译时"ab"对象放在String pool里,即栈内存里                    
String str4=str1+"b";
//这个运行时的运算后产生了一个新的对象"ab"
//str3==str5 为false的官方解释(java规范):在运行时计算的字符串是新创建的,因此不同。或者理解为:在运行期计算的字符串是即时创建的,所以二者是不同的对象。
System.out.println(str1==str1_1);//true
System.out.println(str4=="ab");//false
System.out.println(str3=="ab");  //true
System.out.println(str3.getClass());
System.out.println(str4.getClass());
//System.out.println(new String("a"+"b") ==new String("a"+"b"));
//  new一次就产生一个新的对象,new出来的对象都放在堆内存里面。
               
                /* 另一种解说——字符串驻留(保留)问题。str3=="ab" 结果为true,这是一个字符串驻留效果 ,
                 * (string + string )是可合并的字符串,驻留效果有效。
                 *但在动态字符串(string+variable(变量)、variable+variable)中,字符串的驻留效果无效。
                 */[/code]听说这种题在面试中会有,实际开发很少用到的,如果想更深入,那继续查找资料。
第一次正规回帖,有错误之处,请指出。
[ 本帖最后由 覃俊瑞 于 2011-07-21  19:49 编辑 ]
回复 使用道具 举报
黑马网友  发表于 2011-7-21 23:37:26
报纸
很详细,谢谢你们 ,我懂了 呵呵
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马