equals /==的区别详细讲解

来源:互联网 发布:java项目分享 编辑:程序博客网 时间:2024/05/16 09:49

1.   检查对象是否相等  
  关系运算符==和!=也适用于所有对象,但它们的含义通常会使初涉Java领域的人找不到北。下面是一个例子:  
   
   
  //:   Equivalence.java  
   
  public   class   Equivalence   {  
      public   static   void   main(String[]   args)   {  
          Integer   n1   =   new   Integer(47);  
          Integer   n2   =   new   Integer(47);  
          System.out.println(n1   ==   n2);  
          System.out.println(n1   !=   n2);  
      }  
  }   ///:~  
   
  其中,表达式System.out.println(n1   ==   n2)可打印出内部的布尔比较结果。一般人都会认为输出结果肯定先是true,再是false,因为两个Integer对象都是相同的。但尽管对象的内容相同,句柄却是不同的,而==和!=比较的正好就是对象句柄。所以输出结果实际上先是false,再是true。这自然会使第一次接触的人感到惊奇。  
  若想对比两个对象的实际内容是否相同,又该如何操作呢?此时,必须使用所有对象都适用的特殊方法equals()。但这个方法不适用于“主类型”,那些类型直接使用==和!=即可。下面举例说明如何使用:  
   
   
  //:   EqualsMethod.java  
   
  public   class   EqualsMethod   {  
      public   static   void   main(String[]   args)   {  
          Integer   n1   =   new   Integer(47);  
          Integer   n2   =   new   Integer(47);  
          System.out.println(n1.equals(n2));  
      }  
  }   ///:~  
   
  正如我们预计的那样,此时得到的结果是true。但事情并未到此结束!假设您创建了自己的类,就象下面这样:  
   
   
  //:   EqualsMethod2.java  
   
  class   Value   {  
      int   i;  
  }  
   
  public   class   EqualsMethod2   {  
      public   static   void   main(String[]   args)   {  
          Value   v1   =   new   Value();  
          Value   v2   =   new   Value();  
          v1.i   =   v2.i   =   100;  
          System.out.println(v1.equals(v2));  
      }  
  }   ///:~  
   
  此时的结果又变回了false!这是由于equals()的默认行为是比较句柄。所以除非在自己的新类中改变了equals(),否则不可能表现出我们希望的行为。不幸的是,要到第7章才会学习如何改变行为。但要注意equals()的这种行为方式同时或许能够避免一些“灾难”性的事件。  
  大多数Java类库都实现了equals(),所以它实际比较的是对象的内容,而非它们的句柄。

thinking   in   java里面讲的太复杂  
  没有windows编程经验的人会分不清楚什么是句柄  
  都是翻译惹得祸,翻译出来的书多是垃圾  
  这么说==比较的是地址  
  java中有一个堆和栈的概念  
  一般的数据类型,比如int,float,就在内存栈中画一个区域  
  然后直接把数据写到栈里面去  
  而如果是类,比如String,那么java的储存原理是这样的  
  先在内存堆中划出一片区域,然后把这片区域的地址储存在栈里面  
  而==比较的是栈里面的值  
  所以,a=1,a==1的值是true  
  但是对于一个类来说,比如String   a="aaa";  
  那么处理的方式是这样的  
  先在内存中划出一片区域,然后把"aaa"放进去  
  然后把首地址的位置告诉栈,这样栈里面存的就是地址也就是thinking   in   java里面说的句柄  
  那么很好理解了,我们再new一个String   b="aaa";  
  很明显,此时计算机又会去划一个区域给b,那么这个区域肯定和原来a的区域是不同的  
  虽然值一样,但是栈里面的值不同,所以a==b肯定是错误的  
  那么再来谈谈a=b这个概念,=号是引用赋值,也就是把栈里面的东西拷贝  
  那么很明显,如果你定义成这样  
  String   a="aaa";  
  a=b;  
  那么a==b的值是true;  
  最后来说一下equals这个方法  
  这个方法是基类的几大方法之一  
  其它几个方法是wait(),notify(),notifyAll(),getClass(),hashcode(),toString()  
  equals方法的道理很简单,就是为了防止上面我说的那种情况的发生  
  因为类(尤其是实体类)如果要比较是否相等  
  那么我们更关心的是类的属性(也就是类变量)是否相等,对么?  
  那么如果一个类  
  class   A{  
  int   a;  
  }  
  我定义一个方法public   static   void   main(String[]   args){  
  A   a=new   A();  
  a.a=3;  
  A   b=new   A();  
  b.a=3;  
  }  
  如果没有定义equals方法,那么很显然,a无法等于b,做对比肯定错误  
  因为栈的值是不同的,那如果我想对比a和b呢?  
  用一个equals方法  
  方法如下(在A中定义)  
  public   boolean   equasl(A   a)  
  {  
  if(this.a==a)  
  return   true;  
  else   return   false;  
  }  
  我们重写/覆盖/隐藏了Object类中的equals方法,原来的方法还是在对比栈,不如用==  
  那么重写equals()方法以后,我们要比较A的两个对象是否相等  
  我们就用a.equals(b)来判断