黑马程序员技术交流社区

标题: 求指教:下面的代码片段的输出是什么? [打印本页]

作者: 小丑的媳妇2    时间: 2013-3-6 12:15
标题: 求指教:下面的代码片段的输出是什么?
今天看到一道习题,本人是初学者,请高手看一下下面的代码片段的输出是什么?这道习题书上没有给出答案!
Object s1 = new String("Hello");
Object s2 = new String("Hello");
if(s1 == s2)
{
  System.out.println("s1 and s2 are ==");
}
else if (s1.equals(s2))
{
  System.out.println("s1 and s2 are equals()");
}

我自己感觉应该是s1 and s2 are equals() 但是不确定 请高手指教!
作者: 小丑的媳妇2    时间: 2013-3-6 12:16
补充:如果这样写 结果应该是什么

Object s1 = "Hello";
Object s2 = "Hello";
if (s1 == s2)
{
System.out.println("s1 and s2 are ==");
}
else if (s1.equals(s2))
{
System.out.println("s1 and s2 are equals()");
}
作者: 谢辉林    时间: 2013-3-6 12:27
建议你看看equals和==的区别就明白是怎么回事了
http://www.cnblogs.com/asher/archive/2012/12/26/2834757.html
作者: scott0610    时间: 2013-3-6 12:31
      当使用"=="来判断两个变量是否相等时,如果两个变量是基本数据类型的变量,且都是数值型(不一定要求数据类型严格相同),则只要两个变量的值相等,则使用"=="判断将返回true。  但对于两个引用类型的变量,必须它们指向同一个对象时,"=="判断才会返回true;
      当程序需要判断两个引用变量是否相等时,并不要求两个引用变量指向同一个对象。比如两个字符串变量进行比较。只要求它们引用变量字符串里包含的字符序列相同即可,则用equals判断。   希望对你有所帮助。
作者: 邹学良    时间: 2013-3-6 13:57
"=="比较的是数据在栈中的地址值是否相同,而equale比较的是数据在堆中的内容是否相同
执行
Object s1 = new String("Hello");
Object s2 = new String("Hello");
if(s1 == s2)
{
  System.out.println("s1 and s2 are ==");
}
else if (s1.equals(s2))
{
  System.out.println("s1 and s2 are equals()");
}
时,每调用一次new关键字会产生两个新的对象,一个在堆中,一个在栈中,简而言之就是肯定会产生一个新对象,所以引用对象S1和S2在栈中的哈希地址指向不相,所以S1和S2在堆中的内容同为Hello,所以s1.equals(s2)为真

当执行                Object s1 = "Hello";
                Object s2 ="Hello";
                if(s1 == s2)
                {
                  System.out.println("s1 and s2 are ==");
                }
                else if (s1.equals(s2))
                {
                  System.out.println("s1 and s2 are equals()");
                }
时,S1和S2因为是直接赋值,JVM会首先在栈对象池中查找有没有同样的字符串,如果有的话就直接让它指向该字符串,如果没有就会new一个。所以S1和S2的栈中的地址指向为同一个,S1==S2返回真,
作者: 克零岚    时间: 2013-3-6 15:10
本帖最后由 克零岚 于 2013-3-6 15:17 编辑

呵呵,女孩们的直觉有的时候真的挺管用的,对呀,是你想的输出结果
你的代码:
Object s1 = new String("Hello");
Object s2 = new String("Hello");
if(s1 == s2)                          //s1和s2分别都是对象的引用,对象的引用是放在堆中的,他们的值是字符串“hello”的地址,但对象的引用s1和s2在堆中的地址是不一样的,
{                                           //“==”比较的是对象的引用本身是不是相同,即比较的是s1和s2的在堆中的地址是否一样,很显然不一样,所以不会执行
  System.out.println("s1 and s2 are ==");
}
else if (s1.equals(s2))                                  //equals()比较的是对象的引用所指向的内容是不是一样,s1指向字符串hello,s2也指向字符串hello,hello存在于字符串池中,只有一个helllo
{                                                                 //所以,它们指向的是同一个字符串hello,因为是为了节省内存空间
  System.out.println("s1 and s2 are equals()");
}

你的第二种写法:
Object s1 = "Hello";
Object s2 = "Hello";
if (s1 == s2)
{
System.out.println("s1 and s2 are ==");   //执行的是这一行
}
else if (s1.equals(s2))
{
System.out.println("s1 and s2 are equals()");
}

说明:java运行环境有一个字符串池。比如String str="abc"时,会首先查看字符串池中是否存在字符串"abc",如果存在则直接将"abc"赋给str,如果不存在则会先在字符串池中新建一个字符串"abc",然后再将其赋给str,你的Object s1 = "Hello"; Object s2 = "Hello";  s1和s2指向同一个对象,当然为true

作者: 张卫刚    时间: 2013-3-6 15:51
分析问题,多背东西提高分析能力
作者: amen0205    时间: 2013-3-6 23:12
对于引用型变量而言   == 用来看他们的的地址值是否相同,即他们是不是同一个对象,对于例子1而言,你new了个字符串,他们的地址值是不一样的,所以第一个if不输出   但对于equals   String中复写了Object类中的equals方法,在这里用来比较两个字符串的内容是否相同,所以会输出else后的语句

你二楼的第二个问题:Object s1 = "Hello"; 和Object s2 = "Hello";   都会指向字符串池中的"Hello",即他们是同一个对象,当然内容也相同,所以会输出第一个if的语句。




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