A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

class  Test
{
public static void main(String[] args)
{
  String sr1 = "ab";
  String sr2 = new String("ab");
  System.out.println(sr1==sr2);
  System.out.println(sr1.equals(sr2));
}
}
运行结果一个是:false
                       true


问下,为什么结果是这样的啊? 到底有什么区别啊?

点评

哥,这个问题我在论坛里面最起码看过十遍,找找其他帖子吧,答案很详细~  发表于 2012-6-11 20:13

9 个回复

倒序浏览
本帖最后由 胡卿 于 2012-6-11 19:29 编辑
  1. class  Test
  2. {
  3. public static void main(String[] args)
  4. {
  5.   String sr1 = "ab";
  6.   String sr2 = new String("ab");
  7.   System.out.println(sr1==sr2);//==比较的是字符串内容,所以返回值为true
  8.   System.out.println(sr1.equals(sr2));
  9. //equals比较的是引用类型,所以返回false(sr1的引用地址与sr2的引用地址不一样)

  10. }
  11. }

  12. //如果想返回真,就应该改成:
  13. class  Test
  14. {
  15. public static void main(String[] args)
  16. {
  17.   String sr1 = "ab";
  18.   String sr2 = sr1 ;
  19.   System.out.println(sr1==sr2);
  20.   System.out.println(sr1.equals(sr2));

  21. }
  22. }


复制代码
回复 使用道具 举报
String str = "ab"创建对象的过程
1 首先在常量池中查找是否存在内容为"abc"字符串对象
2 如果不存在则在常量池中创建"abc",并让str引用该对象
3 如果存在则直接让str引用该对象
String str = new String("ab")创建实例的过程
1 首先在堆中(不是常量池)创建一个指定的对象"abc",并让str引用指向该对象
2 在字符串常量池中查看,是否存在内容为"abc"字符串对象
3 若存在,则将new出来的字符串对象与字符串常量池中的对象联系起来
4 若不存在,则在字符串常量池中创建一个内容为"abc"的字符串对象,并将堆中的对象与之联系起来

所以String str1 = "abc",str1引用的是常量池(方法区)的对象,而String str2 = new String("abc"),
str2引用的是堆中的对象,所以内存地址不一样,但是内容一样,所以==为false,而equals是true
回复 使用道具 举报
楼主要记住:String类是final类,那么该类的对象一旦建立就不能改变。
  String st1="abc",String st2=new String ("abc"), 这里很明显是建立了  st1和 st2两个对象,  那么对(st1==st2)的比较当然是false
   至于(st1.equals(st2)),一般的是对引用的地址进行比较,但是String类覆盖了Object类中的equals()方法,使其比较的是 内容。 这两个字符串的内容相同,所以返回 true
回复 使用道具 举报
胡卿 发表于 2012-6-11 19:25

==是false.
equals是true...

你这个回答有误吧。。。
回复 使用道具 举报
本帖最后由 wyl530274554 于 2012-6-11 20:05 编辑

String 类重写了Object的equals方法,如下:

equals
public boolean equals(Object anObject)将此字符串与指定的对象比较。当且仅当该参数不为 null,并且是与此对象表示相同字符序列的 String 对象时,结果才为 true。

==比值两边的值

从内存分析:

字符串常量全部存在于内存中的“字符串池”内,而且不会重复,所以sr1和sr2指向同一内存数据
再根据String类重写的equals定义,就可得知结果。

我这样理解

比较.png (17.43 KB, 下载次数: 32)

equals

equals
回复 使用道具 举报

此处 ==是判断两个对象是否是同一个对象
        equals是进行值的判断
class  Test
{
public static void main(String[] args)
{
  String sr1 = "ab";
  String sr2 = new String("ab");
  System.out.println(sr1==sr2);//str1与str2是两部同对象,false
  System.out.println(sr1.equals(sr2));//str与str2内容一样 true
}
}




回复 使用道具 举报
本帖最后由 王广丛 于 2012-6-12 01:09 编辑

这个问题应该抓药是涉及到的java中对象的存储问题,
String是一个特殊的包装类数据。可以用:
String str = new String("abc");
String str = "abc";
两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。
而第二种是先在堆栈中创建一个对String类的对象引用变量str,然后查找堆栈中有没有存放"abc",如果没有,则将"abc"存放进堆栈,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。
而对于==和equals的区别就没必要多说了,一个是比较的存储地址,一个是比较的应用值是否相同
具体的java对象存储楼主可以看看我的这篇blog:http://www.rolfwang.com/technology/259.html
回复 使用道具 举报
class  Test
{
public static void main(String[] args)
{
   String sr1 = "ab";    //这句运行完后,在内存中产生一个对象
   String sr2 = new String("ab");   //这句话运行完成后,在内存中产生两个对象
   System.out.println(sr1==sr2);   //== 他比较的是一个对象在内存中的地址值,sr1和sr2在内存中地址肯定不一样,返回false.
   System.out.println(sr1.equals(sr2));//String类中的equals方法被覆写了,用于判断字符串是否相等,sr1和sr2都是"ab",所以返回true.

}
}

还有补充一点 1楼的胡卿同学 你的==和equals说反了.
回复 使用道具 举报
==比较的是地址,两个对象的地址不同所以为false
equals比较的是值,两个对象的值相同所以为true
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马