黑马程序员技术交流社区

标题: 关于String类的一道面试题,跪求解答 [打印本页]

作者: _etc    时间: 2015-3-28 22:03
标题: 关于String类的一道面试题,跪求解答
我一直搞不懂,这个一个求解字符串相是否相等的问题的问题,第一处为何是flase,在线跪等高人解答。。



public static void main(String[] args) {
        String s1 = "a";
        String s2 = "b";
        String s3 = "ab";
        System.out.println(s3 == s1 + s2);//这个地方
        System.out.println(s3 == "a" + "b");
}


作者: AnElse    时间: 2015-3-28 23:04
System.out.println(s3 == s1 + s2);因为s1,s2是变量,虚拟机时不知道它为字符串常量的,所以会另外给它开辟空间。
作者: natsu647    时间: 2015-3-28 23:13
这里的s1 , s2 都是对象 ,所以s3 == s1 + s2 只是判断s3与( s1 + s2 )是否是同一个内存地址。
判断内容是否相同应该用s3.equals(s1 + s2)  。
作者: 466273082    时间: 2015-3-28 23:17
s3是一个对象,s1,与s2是两个对象,肯定不等呀
作者: hhh233    时间: 2015-3-28 23:26
natsu647 发表于 2015-3-28 23:13
这里的s1 , s2 都是对象 ,所以s3 == s1 + s2 只是判断s3与( s1 + s2 )是否是同一个内存地址。
判断内容 ...

没有new  应该都在常量池里吧
作者: 复仇的撒旦    时间: 2015-3-28 23:37
hhh233 发表于 2015-3-28 23:26
没有new  应该都在常量池里吧

String是一个类,所以s1和s2都在堆内存中,比较的是默认地址值,2楼正解
作者: hhh233    时间: 2015-3-29 08:46
复仇的撒旦 发表于 2015-3-28 23:37
String是一个类,所以s1和s2都在堆内存中,比较的是默认地址值,2楼正解
String s1 ="a";String s2 ="a";
s1==s2  这个结果为true  是说明他们默认的地址是一样的吗?

作者: chenlanaq    时间: 2015-3-29 10:38
hhh233 发表于 2015-3-29 08:46
String s1 ="a";String s2 ="a";
s1==s2  这个结果为true  是说明他们默认的地址是一样的吗?
...

是的,字符串的常量,都是用的同一个。
s3=s1+s2实际上是new了一个String出来的
你去先把s3赋值s1+s2,s3=s1+s2,然后再判断s3==s1+s2试试就知道了,它还是不同的,都是new出来的。
作者: 翰墨    时间: 2015-3-29 11:33
String s4=s1+s2;
System.out.println(s4);//ab
System.out.println(s4==s3);//false
楼主我验证了一下,比较s4==s3,结果还是false,说明s3 == s1 + s2在比较的时候做了两次运算,先把s1+s2赋值给s4,在比较s4==s3,即比较s4和s3的地址是否相同
作者: 冻了冬天    时间: 2015-3-29 11:43
哥们你还没懂啊
作者: lwj123    时间: 2015-3-29 11:45
        String s1 = "a";
        String s2 = "b";
        String s3 = "ab";
        System.out.println(s3 == s1 + s2);//这个地方
        System.out.println(s3 == "a" + "b");
s3 == s1 + s2:
s1,s2是变量,在字符串连接时,如果有变量的出现,JVM不会把它进行宏替换的,也就是说在池里去找对应的字符串来代替。也就是不能在编译时就确定连接后的值。所以一个输出返回的是false

s3 == "a" + "b":在编译时期就已经可以将s3所指向的值确定了,所以返回的是true
作者: _etc    时间: 2015-3-29 19:43
哥们今天问同学了,感谢各位。
作者: JARVIS_YJ    时间: 2015-3-29 19:54
同题。。。。
作者: 杨大萌    时间: 2015-3-29 20:00
不能直接用==运算符来直接判断对象
作者: P李勇    时间: 2015-3-29 20:00
我想问的是s3==“a”+“b”为什么true啊
第一个倒是明白。。。
作者: _etc    时间: 2015-3-29 20:09
P李勇 发表于 2015-3-29 20:00
我想问的是s3==“a”+“b”为什么true啊
第一个倒是明白。。。

字符串的值不能改变。存在内存中就不能改变,"ab"早就存在在内存中了。
作者: P李勇    时间: 2015-3-29 20:17
_etc 发表于 2015-3-29 20:09
字符串的值不能改变。存在内存中就不能改变,"ab"早就存在在内存中了。

a+b没有构造新的字符串哈,是去之前构造中找的,找到了所以返回的和s3的地址一样,所以true哈?
作者: _etc    时间: 2015-3-29 20:19
P李勇 发表于 2015-3-29 20:17
a+b没有构造新的字符串哈,是去之前构造中找的,找到了所以返回的和s3的地址一样,所以true哈? ...

对的           
作者: godot    时间: 2015-3-30 11:22
== 判断地址值
作者: tubao1991    时间: 2015-3-30 11:51
切记 String 是一个类就好理解了。
作者: 李明全    时间: 2015-3-30 14:50
这里的s1 , s2 都是对象 ,所以s3 == s1 + s2 只是判断s3与( s1 + s2 )是否是同一个内存地址。
作者: xj刘博    时间: 2015-3-31 13:32
本帖最后由 xj刘博 于 2015-3-31 13:36 编辑
  1. <div class="blockcode"><blockquote>

  2. public class Text {
  3.         public static void main(String[] args) {
  4.                 String s1 = "a";// s1是一个类的类型变量,“a”是一个对象
  5.                 // 初始化后要为a在内存中开辟一个空间
  6.                 String s2 = "b";
  7.                 String s3 = "ab";
  8.                 System.out.println(s3 == s1 + s2);// 这里比较的是内存地址,所以为false
  9.                 System.out.println(s3 == "a" + "b");// 这里比较的是常量的值,因为a和b已经在常量池中存在了,
  10.                                            //所以就不会为s3中的ab单独开辟空间了,a和b会直接指向ab,所以相等
  11.         }                                   
  12. }
复制代码



作者: 李明全    时间: 2015-4-1 00:31
这里的s1 , s2 都是对象 ,所以s3 == s1 + s2 只是判断s3与( s1 + s2 )是否是同一个内存地址。
作者: 妖妖    时间: 2015-4-1 19:39
当我们使用字符串的时候,==是比较的两个字符串是不是指向同一个对象。程序在运行的时候会创建一个字符串缓冲池,程序会把字符串常量(比如说,题目中的“a”,“b”“ab”)放入字符串缓冲池中。现在我们将题中的“a”+“b”赋值给String 类型的s4,我们在创建字符串的时候,程序会首先在这个stirng缓冲池中寻找是否有相同值得对象,所以在进行“a”+“b”的时候,程序找到了“ab”,这时我们就将s4指向了“ab”,所以,现在“ab”就与s4指向了同一个对象,所以就会输出“true”。
但是,我们在进行变量的运算时,就不一样了,在进行s1 + s2的时候,他们会将得到的字符串对象储存在各自的内存中,而不是放在缓冲池中。尽管结果是一样的,但是因为不是指向同一个对象的原因,所以就有了两个不同的结果。我记得在视频中有涉及到类似的问题啊!
作者: 飞翔的侠客604    时间: 2015-4-1 20:33
受教了,感谢楼主分享
作者: DxxD    时间: 2015-4-1 21:04
可以按楼上说的试着用equals一下。。。。
作者: WanLum    时间: 2015-4-28 22:52
这里的s1 , s2 都是对象 ,所以s3 == s1 + s2 只是判断s3与( s1 + s2 )是否是同一个内存地址。
判断内容是否相同应该用s3.equals(s1 + s2)  。,这个地方好像是错的啊,,,兄弟
作者: ccsd999    时间: 2015-4-28 22:53
谢谢分享




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