黑马程序员技术交流社区

标题: 关于字符串的问题 [打印本页]

作者: 王少岩    时间: 2012-8-9 14:36
标题: 关于字符串的问题
本帖最后由 王少岩 于 2012-8-9 15:42 编辑

String s="a";
String s1=s+"b";
String s2=s+"b";
System.out.println(s1.equals(s2));//true
System.out.println(s1==s2);//为什么结果是false。s1和s2的内容相同,字符串都存在与常量池中,既然它们的内容都相同,那么它们的指向的就应该是同一个值,所以它们所代表的地址值应该是同一个啊,但为什么会是false
final String s="a";
String s1=s+"b";
String s2=s+"b";
System.out.println(s1.equals(s2));//true
System.out.println(s1==s2);//true这又是为什么,多个final跟上面有了哪些区别?
作者: 黑马-唐磊    时间: 2012-8-9 14:47
本帖最后由 黑马-唐磊 于 2012-8-9 16:34 编辑

因为“==”比较的是两个变量的值是否相等,对于引用表示两个变量在堆中存储的地址值是否相同及栈中内容是否相同,而equals比较的是两个对象是否对同一对象的引用,即堆中的内容是否相等。在你这个程序中,其实在程序运行时会创建一个缓冲池,当使用String s1=s+"b"时,程序会在String缓冲池寻找相同对象,在第一个程序中s会先放到缓冲池中,所以在s1,s2创建的时候,程序中找到相同值的s1将s2引用s1所引用的对象s+"b"。所以当s1.equals(s2)时他们引用同一对象s+"b"则结果为true,因为上文已说过s的值会先放到缓冲池中,当它s给s2时,虽然他们的值相同但它的地址值已经放生了变化所以s1==s2
结果为false,为什么加final后结果都为true呢?是因为定义final后就表示两个变量的地址值不允许改变,定义后它们所引用对象仍是相同的,地址值也是相同所以结果都为true了
作者: 尤洋    时间: 2012-8-9 15:06
String s1=s+"b";
String s2=s+"b";都有一个“+”的操作,
这导致了他们无法在编译时期就确定
所以s1和s2对应的字符串不放入常量池中,他们有自己的地址空间。 也就相当于创建了两个对象
所以== 后是false。
作者: 王少岩    时间: 2012-8-9 15:22
尤洋 发表于 2012-8-9 15:06
String s1=s+"b";
String s2=s+"b";都有一个“+”的操作,
这导致了他们无法在编译时期就确定

恩,基本认同,但是我感觉应该不是"+"操作,应该是"s"吧,"s"是字符串引用,在编译期不能确定"s"的值,然后就是你说的那个原因吧。
作者: 尤洋    时间: 2012-8-9 15:46
王少岩 发表于 2012-8-9 15:22
恩,基本认同,但是我感觉应该不是"+"操作,应该是"s"吧,"s"是字符串引用,在编译期不能确定"s"的值,然 ...

说“+”操作   只是为了 表述简明一点罢了
写详细了就是 “加上了一个 引用变量s,而 s对应的是什么对象 和“b”相加后又是什么 这些都是未知的,无法在编译时确定”

其实你能问出这个问题,应该对这方面已经有了一些认知了,我
再废话一堆的往上写,既浪费感情,也让人找不到主旨。

作者: 王少岩    时间: 2012-8-9 15:50
恩,了解了,问题解决了




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