问题描述
publicclassStringTest{publicstaticvoidmain(String[]args){Stringa=“ab”;System.out.println(”Stringa=“ab”;”);Stringb=“cd”;System.out.println(”Stringb=“cd”;”);Stringc=“abcd”;Stringd=“ab”+“cd”;if(d==c){System.out.println(”"ab”+”cd”创建的对象“加入了”字符串池中”);}else{System.out.println(”"ab”+”cd”创建的对象“没加入”字符串池中”);}Stringe=a+“cd”;if(e==c){System.out.println(”a+”cd”创建的对象“加入了”字符串池中”);}else{System.out.println(”a+”cd”创建的对象“没加入”字符串池中”);}}}为什么e和c指向的不是同一个对象??请高手做出解释,谢谢。。
解决方案
解决方案二:
如果Stringe="ab"+"cd";那么就是一个对象了,你这样不是
解决方案三:
因为"ab"+"cd"编译器知道它一定是常量"abcd",所以编译过程中就把它直接当作"abcd"了。而a+"cd"由于编译器不知道a这个变量里面是什么东西,所以这个值是运行的时候算出来的,所以是一个新的String。
解决方案四:
这个东西书上讲的很清楚c和e指向两个不同的内存单元他们是不可能等的两个变量的内存单元相等的概率极低的估计你想要判断他们是不是一个类如果你要判断他们是不是一个类那么不能用等号
解决方案五:
要想让他们相等就给e=c这样e就引用了c的地址
解决方案六:
2楼正解。
解决方案七:
对2楼的一点补充:1.通过常量表达式计算的String,计算在编译时进行,并将它作为String字面常量对待。2.通过连接操作得到的String(非常量表达式),连接操作是运行时进行的,会新创建对象,所以它们是不同的。
解决方案八:
因为当编译器运行Stringa=“ab”;时编译器在内存数据空间(就是字符串池)中分配了一个空间,值为“ab”,而在栈内存空间中分配了一个空间,名字叫做a,它的值为地址指向了数据空间的“ab”,(虽然java中没有指针,但实际上java里处处有指针,上面明显就是一个指针的应用)。同理Stringb=“cd”;Stringc=“abcd”;都在数据空间分配了空间“cd”空间“abcd”,而在栈内存中分配了空间b指向“cd”,空间c指向“abcd”语句Stringd=“ab”+“cd”;以为“ab”+“cd”是字符串相加,相当于“abcd”;这个时候编译器有个优化,并没有在数据空间分配一个新的内存来存放“abcd”,以为它发现已经有个“abcd”存在,所以他把存在的“abcd”的地址赋值给在栈内存空间新分配的空间d,当做if(d==c)时,d和c里存放的都是数据空间中“abcd”的地址,所以d等于c,if判断成立容器内我们再来看看Stringe=a+“cd”;语句编译器是如何编译的首先一样在栈内存空间中分配了一个新的空间e,而a+“cd”编译器编译时,a为一个引用(因为a为一个变量,这里引用了这个变量),在java中,所用的引用都会在堆内存空间中分配一个空间,所以此时在堆内存空间中开辟了一个空间,这个空间存放了a的值(就是数据空间中“ab”的地址)和数据空间中“cd”的地址,而此时在栈空间中e的值为a+“cd”在堆空间得地址,此时在做if(e==c)e为a+“cd”在堆空间得地址,c为“abcd”在数据空间中的地址结果明显是不相等的!如果此时要得到if(e==c)为true,需要用到函数equalsif()方法。
解决方案九:
呵呵上面有不少地方打错了咳为什么在这个论坛不能对自己发出的帖子进行重新编译呢?因为当编译器运行Stringa=“ab”;时编译器在内存数据空间(就是字符串池)中分配了一个空间,值为“ab”,而在栈内存空间中分配了一个空间,名字叫做a,它的值为一个地址指向了数据空间的“ab”,(虽然java中没有指针,但实际上java里处处有指针,上面明显就是一个指针的应用)。同理Stringb=“cd”;Stringc=“abcd”;都在数据空间分配了空间“cd”空间“abcd”,而在栈内存中分配了空间b指向“cd”,空间c指向“abcd”语句Stringd=“ab”+“cd”;因为“ab”+“cd”是字符串相加,相当于“abcd”;这个时候编译器有个优化,并没有在数据空间分配一个新的内存空间来存放“abcd”,因为它发现已经有个“abcd”存在,所以它把存在的“abcd”的地址赋值给在栈内存空间新分配的空间d,当做if(d==c)时,d和c里存放的都是数据空间中“abcd”的地址,所以d等于c,if判断成立让我们再来看看Stringe=a+“cd”;语句,编译器是如何编译的首先一样在栈内存空间中分配了一个新的空间e,而a+“cd”编译器编译时,a为一个引用(因为a为一个变量,这里引用了这个变量),在java中,所用的引用都会在堆内存空间中分配一个空间,所以此时在堆内存空间中开辟了一个空间,这个空间存放了a的值(就是数据空间中“ab”的地址)和数据空间中“cd”的地址,而此时在栈空间中e的值为a+“cd”在堆空间得地址,此时在做if(e==c)e为a+“cd”在堆空间得地址,c为“abcd”在数据空间中的地址结果明显是不相等的!如果此时要得到if(e==c)为true,需要用到函数equals()方法。
解决方案十:
字面常量相加在编译器就确定了,所以放在常量池了后者的一个对象和一个字面常量相加发生在运行期,而且是StringBuilder.toString()的结果,这个对象放在栈里面了
解决方案十一:
路过学习
解决方案十二:
引用7楼csliyu的回复:
因为当编译器运行Stringa=“ab”;时编译器在内存数据空间(就是字符串池)中分配了一个空间,值为“ab”,而在栈内存空间中分配了一个空间,名字叫做a,它的值为地址指向了数据空间的“ab”,(虽然java中没有指针,但实际上java里处处有指针,上面明显就是一个指针的应用)。同理Stringb=“cd”;Stringc=“abcd”;都在数据空间分配了空间“cd”空间“abcd”,而在栈内存中分配了空间b指向“cd”,空间c指向“abcd”语句Stringd=“ab”+“cd”;以为“ab”+“cd”是字符串相加,相当于“abcd”;这个时候编译器有个优化,并没有在数据空间分配一个新的内存来存放“abcd”,以为它发现已经有个“abcd”存在,所以他把存在的“abcd”的地址赋值给在栈内存空间新分配的空间d,当做if(d==c)时,d和c里存放的都是数据空间中“abcd”的地址,所以d等于c,if判断成立容器内我们再来看看Stringe=a+“cd”;语句编译器是如何编译的首先一样在栈内存空间中分配了一个新的空间e,而a+“cd”编译器编译时,a为一个引用(因为a为一个变量,这里引用了这个变量),在java中,所用的引用都会在堆内存空间中分配一个空间,所以此时在堆内存空间中开辟了一个空间,这个空间存放了a的值(就是数据空间中“ab”的地址)和数据空间中“cd”的地址,而此时在栈空间中e的值为a+“cd”在堆空间得地址,此时在做if(e==c)e为a+“cd”在堆空间得地址,c为“abcd”在数据空间中的地址结果明显是不相等的!如果此时要得到if(e==c)为true,需要用到函数equalsif()方法。
相当的完整
解决方案十三:
e.equal(c)=true
解决方案十四:
七楼的,我有点不明白,你的a一会指向数据空间,一会指向堆,什么意思啊?
解决方案十五:
因为当编译器运行Stringa=“ab”;时编译器在内存数据空间(就是字符串池)中分配了一个空间,值为“ab”,而在栈内存空间中分配了一个空间,名字叫做a,它的值为地址指向了数据空间的“ab”,a为一个引用(因为a为一个变量,这里引用了这个变量),在java中,所用的引用都会在堆内存空间中分配一个空间,所以此时在堆内存空间中开辟了一个空间,这个空间存放了a的值不矛盾吗?
解决方案:
引用2楼zrcvic的回复:
因为 "ab" + "cd" 编译器知道它一定是常量 "abcd",所以编译过程中就把它直接当作 "abcd" 了。而 a + "cd" 由于编译器不知道 a 这个变量里面是什么东西,所以这个值是运行的时候算出来的,所以是一个新的 String。
正解
解决方案:
正好有此疑问,收藏了。
解决方案:
引用14楼kangbaoxing的回复:
因为当编译器运行Stringa=“ab”;时编译器在内存数据空间(就是字符串池)中分配了一个空间,值为“ab”,而在栈内存空间中分配了一个空间,名字叫做a,它的值为地址指向了数据空间的“ab”,a为一个引用(因为a为一个变量,这里引用了这个变量),在java中,所用的引用都会在堆内存空间中分配一个空间,所以此时在堆内存空间中开辟了一个空间,这个空间存放了a的值不矛盾吗?
是e指向堆内存应为是e引用了a,我说的是a为一个引用并不是a指向堆内存而此时在栈空间中e的值为a+“cd”在堆空间得地址说明e指向这个新分配的内存空间这个空间存放了a的值说的是新开辟的内存空间存放了a的值,就是新开辟的内存空间指向数据空间中的“ab”,实际上在堆内存中的这个内存空间里有分割成两个空间,一个指向数据空间中的“ab”,另指向数据空间中的“cd”
解决方案:
如果是初学者,建议别在这上面纠缠,学三个月,自然清楚了。
解决方案:
讨论这么多有什么用?这完全取决于编译器的行为。你可以反编译一下看一下javac做了些什么?Stringa="ab";Stringb="cd";Stringc="abcd";Stringd="abcd";Stringe=(newStringBuilder(String.valueOf(a))).append("cd").toString();这是我看到的。你觉得不爽可以自己写个智能编译器,把e也解释成"abcd",不过这可能和java规范有冲突。^^
解决方案:
去理解一下字符串对象吧,还有就是equals()和==的区别,最好了解一下内存分配
解决方案:
晕死我了,原来是Java
解决方案:
//DecompiledbyDJv3.7.7.81Copyright2004AtanasNeshkovDate:2009-10-1817:32:02//HomePage:http://members.fortunecity.com/neshkov/dj.html-Checkoftenfornewversion!//Decompileroptions:packimports(3)//SourceFileName:Test.javaimportjava.io.PrintStream;publicclassStringTest{publicStringTest(){}publicstaticvoidmain(Stringargs[]){Strings="ab";System.out.println("Stringa="ab";");Strings1="cd";System.out.println("Stringb="cd";");Strings2="abcd";Strings3="abcd";if(s3==s2)System.out.println(""ab"+"cd"u521Bu5EFAu7684u5BF9u8C61"u52A0u5165u4E86"u5B57u7B26u4E32u6C60u4E2D");elseSystem.out.println(""ab"+"cd"u521Bu5EFAu7684u5BF9u8C61"u6CA1u52A0u5165"u5B57u7B26u4E32u6C60u4E2D");Strings4=(newStringBuilder()).append(s).append("cd").toString();if(s4==s2)System.out.println("a+"cd"u521Bu5EFAu7684u5BF9u8C61"u52A0u5165u4E86"u5B57u7B26u4E32u6C60u4E2D");elseSystem.out.println("a+"cd"u521Bu5EFAu7684u5BF9u8C61"u6CA1u52A0u5165"u5B57u7B26u4E32u6C60u4E2D");}}
我什么都不想说,贴出源代码大家都好看!
解决方案:
ding...............