黑马程序员技术交流社区

标题: String 是否相等问题!看清语句,为啥呢 [打印本页]

作者: hejinzhong    时间: 2014-8-21 06:45
标题: String 是否相等问题!看清语句,为啥呢

  1.         //第一种形式
  2. class Test1   
  3. {
  4.         public static void main(String[] args)
  5.         {       
  6.                 String s1 = "a";
  7.                 String s2 = "a"+ "b";
  8.                 String s3 = "ab";
  9.                 //当输出s2和s3,其内容都为ab,下面的语句是true,那么下面呢
  10.                 System.out.println(s2==s3);
  11.         }
  12. }

  13.         //第二种形式
  14. class Test2
  15. {
  16.         public static void main(String[] args)
  17.         {       
  18.                 String s1 = "a";
  19.                 String s2 = s1+ "b";
  20.                 String s3 = "ab";
  21.                 //当输出s2和s3,其内容都为ab,下面的语句是false,这又是为啥呢
  22.                 System.out.println(s2==s3);
  23.         }
  24. }

  25. ps:我想知道的是JVM是如何处理这两种形式的字符串?
复制代码


作者: 依然超级赛亚人    时间: 2014-8-21 07:26
  之前也在论坛看到过不少类似问题,据说String s1="a"+"b";这样直接相连接的创建方式都可以在编译时就确定下来,可以直接引用常量池中的。而  String s2=s1+"c";这样涉及变量相加的情况不能在编译时确定下来不能引用常量池中的字符串。
作者: 杜工    时间: 2014-8-21 07:37
==有两种意思,一是比较值是否相同,二是比较对象是否为同一个(指向同一个地址)。Test1中,s2和s3指向同一栈中的数据,共享数据ab,所以相同。Test2中,s1一旦创建,值“a”就不会改变,所以s2是两个对象相加,会创建新的对象,且和s3为不同的对象,所以s2==s3为false。个人理解哈。
作者: Joemi    时间: 2014-8-21 08:39
支持3楼的说法
作者: 华谦    时间: 2014-8-21 09:05
第二个肯定为false,第一个为true是因为“+”这个符号相当于把两个字符串连在一起
作者: 菜鸟一号    时间: 2014-8-21 09:12
依然超级赛亚人 发表于 2014-8-21 07:26
之前也在论坛看到过不少类似问题,据说String s1="a"+"b";这样直接相连接的创建方式都可以在编译时就确定 ...

悟空正解
作者: 李章敏    时间: 2014-8-21 09:18
2,3楼说的都对吧                                                
作者: 男人你得有范    时间: 2014-8-21 09:36
表示三楼和我想的一样,哈哈
作者: 复仇者联盟    时间: 2014-8-21 10:01
嗯,这些细节需要我们仔细琢磨。
作者: masai158    时间: 2014-8-21 10:26
小悟空正解
作者: 怀念黑海岸    时间: 2014-8-21 12:50
我也来说点吧:JVM在对类文件进行编译时,有一个优化机制:他会把想加的字符串常量在编译器时就整合成一个新的字符串,你的第一个例子中的s2="a"+"b";a和b这是两个确定的字符,所以jvm编译时就直接给你整合成字符串ab,当你的字节码文件加载到内存中后常量池就已经存在字符串ab了,所以你s3=ab其实也是指的是这个常量。为什么第二个就是false呢,前面说了的,这个机制只针对常量,你第二个例子中s2=s1+"b";jvm在对第二个例子进行编译时他是不会将这句代码进行优化的,因为这句代码中存在被一个变量s1,就像你静态方法中使用一个对象引用会报错一样,jvm是拒绝干这种事情的。这句代码会在jvm被加载进内存中后运行到他时在堆空间临时生成对象s2,而s2的值也是存在于该语句所在方法的栈空间内,两个值放的位置都不同,那么你用==去比较他们的地址肯定为假了。
       以前有一个人在论坛上提过相关问题的,当时我也不太清楚,专门去咨询了一个工作8年的java工程师,这是他给我的解释,我也写了一篇博客,就是讲的这个,如果还不懂的话你可以去看看。
http://blog.sina.com.cn/s/blog_b9c7c2ed0102uxu2.html
作者: 水星不不    时间: 2014-8-21 13:06
要想String相等 要重写equals
作者: 范靖明    时间: 2014-8-21 15:08
在String类中“+”是字符串连接符!
作者: 笑脸迷人    时间: 2014-8-21 18:16
11楼的解释非常犀利~开眼界啊




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