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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张权 中级黑马   /  2012-11-18 11:30  /  2895 人查看  /  13 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 张权 于 2012-11-18 11:33 编辑

class Compare
{
                public static void main(String[] args)
                {
                                String str1 = new String("abc");
                                String str2 = new String("abc");
                                String str3 = str1;
                                System.out.println(str1 == str2);
                                System.out.println(str1.equals(str2));
                                if(str1.equals(str2))
                                                System.out.println("str1 equal str2");
                                else
                                                System.out.println("str1 not equal str2");
                                if(str1.equals(str3))
                                                System.out.println("str1 equal str3");
                                else
                                                System.out.println("str1 equal str3");        
                }        
}以上代码貌似看出来了二者的区别,==比较的是引用的内存地址,所以System.out.println(str1 == str2);
结果是false;而equals比较的是 两个引用变量所指向的对象的内容是否想等,System.out.println(str1.equals(str2));
比较结果是true!!!
但是再看下面代码:
class Compare
{
                Compare(String a){}        
}
class CompareDemo
{
                public static void main(String[] args)
                {
                                Compare c1 = new Compare("abc");
                                Compare c2 = new Compare("abc");
                                System.out.println(c1.equals(c2));
                                System.out.println(c1==c2);
                                
                }        
}为什么这里的equals 和 ==比较结果都是false呢?

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 赞一个!

查看全部评分

13 个回复

正序浏览
equals和==都是地址引用的。但在string中复写了equals方法。改成了比较内容。。
回复 使用道具 举报
张权 中级黑马 2012-11-24 11:27:42
13#
刘腾 发表于 2012-11-18 13:08
equal:是用来比较两个对象内部的内容是否相等的,由于所有的类都是继承自java.lang.Object类的,所以如果没 ...

兄弟回答的很好啊,管理没有加分,可以找管理加分!!
回复 使用道具 举报
==号,他比较的是一个对象在内存中的地址值,
比如2个字符串对象
String s1 = new String("str");
String s2 = new String("str");
如果用==号比较,会返回false,因为创建了两个对象,他们在内存中地址的位置是不一样的。

equals的情况比较复杂,它是java.lang.Object类中的一个方法。因为java中所有的类都默认继承于Object,所以所有的类都有这个方法。

在Object类源码中是这样写的。
public boolean equals(Object obj) {
return (this == obj);
}
他同样使用==号进行内存地址的比较。但是许多java类中都重写了这个方法,比如String。
public boolean equals(Object anObject) {
if (this == anObject) {
     return true;
}
if (anObject instanceof String) {
     String anotherString = (String)anObject;
     int n = count;
     if (n == anotherString.count) {
  char v1[] = value;
  char v2[] = anotherString.value;
  int i = offset;
  int j = anotherString.offset;
  while (n-- != 0) {
      if (v1[i++] != v2[j++])
   return false;
  }
  return true;
     }
}
return false;
    }

String里的方法,如果==号比较不相等,还会进行一下值的比较。
所以equals方法具体的作用要看当前的那个类是如何实现重写父类中该方法的。如果没有重写该方法,那么他和==号等价。
回复 使用道具 举报
受教了 这个我也不太懂
回复 使用道具 举报
== 比较的是两个变量所存储的内容是否变量,对于值类型变量因为他们存储的就是我们能看的见的值内容
比如 int i = 3;
        int j = 3;
        因此 i == j 返回的是true
        但引用类型的变量,实际存储的内容值不是我们直接看的见字面值,而是它所指向的实例的内存地址值
     因此 对应包装类 如
     Integer a = new Integer(3);
        Integer b = new Integer(3);
        a == b 比较的却不是里面的3 而是该类两实例的引用,故这里返回的是false
回复 使用道具 举报
刘腾 高级黑马 2012-11-18 13:08:46
9#
equal:是用来比较两个对象内部的内容是否相等的,由于所有的类都是继承自java.lang.Object类的,所以如果没有对该方法进行覆盖的话,调用的是Object类中的方法,而Object中的equal方法返回的却是==的判断,因此,如果在没有进行该方法的覆盖后,调用该方法是没有任何意义的。
==:是用来判断两个对象的地址是否相同,即是否是指相同的一个对象。比较的是真正意义上的指针操作。
  而JDK类中有一些类覆盖了Object类的equals()方法,比较规则为:如果两个对象的类型一致,并且内容一致,则返回true,这些类有:java.io.file.util.Date,java.lang.string,包装类(Interger,Double等)
比如
Integer int1=new Integer(1);
Integer int2=new Integer(1);


String str1=new String("hello");
String str2=new String("hello");

int1==int2  输出 false  因为不同对象
int1.equals(int2) 输出 true

str1==str2  false
str1.equals(str2)  true
这样解释应该明白了吧。。。
回复 使用道具 举报
张权 中级黑马 2012-11-18 12:54:51
8#
梁枝武 发表于 2012-11-18 12:17
上帝类的equals方法源码是这样的:
public boolean equals(Object obj) {
        return (this == obj);

嗯,知道了,谢谢!!
回复 使用道具 举报
张权 发表于 2012-11-18 12:10
2楼回答的没懂,不过就知道一点,因为没有复写Object类的equals方法,所以就还是相当于==比较的是地址值 ...

上帝类的equals方法源码是这样的:
public boolean equals(Object obj) {
        return (this == obj);
    }
也就是如果不复写equals 那么它跟 ==有同等效果
上帝类是一切类的(直接或间接)父类,如果不复写equals那么默认就是按Object类的equals来比较,比较的是地址值,其他类复写目的是为了让equals比较的不再是地址值而是该类在内容上或逻辑上是否相同
回复 使用道具 举报
==是java语法的内容,像=、<、+等都是语法范围,其功能是不能修改的;
equals是java类库的内容,像println等都是库类里面类的方法,可以通过重写来修改其功能。
回复 使用道具 举报
梁枝武 发表于 2012-11-18 11:55
class Compare
{
                Compare(String a){}        

2楼回答的没懂,不过就知道一点,因为没有复写Object类的equals方法,所以就还是相当于==比较的是地址值,只是,为什么复写后比较的就是对象的内容,而不复写上帝类的equals 方法,比较的就是地址值呢?》
回复 使用道具 举报
2楼回答的没懂,不过就知道一点,因为没有复写Object类的equals方法,所以就还是相当于==比较的是地址值,只是,为什么复写后比较的就是对象的内容,而不复写上帝类的equals 方法,比较的就是地址值呢?》
回复 使用道具 举报
楼上正解,在String类中复写了equals方法
System.out.println(str1.equals(str2));//比较的是对象的内容

而在
System.out.println(c1.equals(c2));//由于你的Compare类没有复写equals方法,效果与==相同,比较的都是地址值
回复 使用道具 举报
本帖最后由 梁枝武 于 2012-11-18 12:03 编辑

class Compare
{
                Compare(String a){}        
}
class CompareDemo
{
                public static void main(String[] args)
                {
                                Compare c1 = new Compare("abc");
                                Compare c2 = new Compare("abc");
                                System.out.println(c1.equals(c2));
                                System.out.println(c1==c2);
                                
                }        
}为什么这里的equals 和 ==比较结果都是false呢?

楼主的这个new的两个Compare类对象,通过构造函数创建了两个字符串,因为它是属于两个对象的内容,虽然两个字符串引用指向的是同一个地址上的值"abc",但比较的时候并不是比较字符串是否equals 或 == 而是比较 你自定义的Compare对象是否equals 或 == 而你创建的对象没有对上帝类的equals进行复写 所以这个c1.equals(c2) 实际上跟 c1==c2 等价的, 都是比较两个Compare对象的地址值,显然他们不等所以两个结果都为false

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马