黑马程序员技术交流社区

标题: "=="和equals方法究竟有什么区别 [打印本页]

作者: lvwenwen88    时间: 2012-1-3 19:53
标题: "=="和equals方法究竟有什么区别
本帖最后由 lvwenwen88 于 2012-1-4 11:18 编辑

"=="和equals方法究竟有什么区别
作者: lvwenwen88    时间: 2012-1-3 19:54
请教各位,谢谢
作者: lvwenwen88    时间: 2012-1-3 19:54
请教各位,谢谢
作者: 章春晓    时间: 2012-1-3 20:02
==是判断两个变量或实例是不是指向同一个内存空间 ,equals是判断两个变量或实例所指向的内存空间存的值是不是相同。

作者: 李盈科    时间: 2012-1-3 20:04
如果equals()方法没有被重写 他的功能和 “==” 是相同的,都是比较两个对象地址是否相同,如果被重写了一般就是比较两个对象的内容是否相同。在String中比较相等就要用equals方法,你可以看一下源代码是被重写的。
作者: 詹英鹏    时间: 2012-1-3 20:19
==来判断两个变量是否相等,如果2个变量是基本类型的变量,
且都是数值型(不一定要求数据类型严格相同),则只要两个变量的值相等,
使用==判断就返回true但对于两个引用类型的变量,
必须他们指向一个对象,==才会返回true,==不可比较类型上没有父子关系的两个对象
如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如Objet obj = new Object();变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。
equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。例如,对于下面的代码:
String a=new String("foo");
String b=new String("foo");
两条new语句创建了两个对象,然后用a,b这两个变量分别指向了其中一个对象,这是两个不同的对象,它们的首地址是不同的,即a和b中存储的数值是不相同的,所以,表达式a==b将返回false,而这两个对象中的内容是相同的,所以,表达式a.equals(b)将返回true。
在实际开发中,我们经常要比较传递进行来的字符串内容是否等,例如,String input = …;input.equals(“quit”),许多人稍不注意就使用==进行比较了,这是错误的,随便从网上找几个项目实战的教学视频看看,里面就有大量这样的错误。记住,字符串的比较基本上都是使用equals方法。
如果一个类没有自己定义equals方法,那么它将继承Object类的equals方法,Object类的equals方法的实现代码如下:
boolean equals(Object o){
return this==o;
}
这说明,如果一个类没有自己定义equals方法,它默认的equals方法(从Object 类继承的)就是使用==操作符,也是在比较两个变量指向的对象是否是同一对象,这时候使用equals和使用==会得到同样的结果,如果比较的是两个独立的对象则总返回false。如果你编写的类希望能够比较该类创建的两个实例对象的内容是否相同,那么你必须覆盖equals方法,由你自己写代码来决定在什么情况即可认为两个对象的内容是相同的。
作者: 颜宗茂    时间: 2012-1-3 21:48
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如Objet obj = new Object();变量obj是一个内存,new Object()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。equals方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。

作者: 林晓波    时间: 2012-1-3 21:51
==是判断两个变量或实例是不是指向同一个内存空间
equals是判断两个变量或实例所指向的内存空间的值是不是相同
实例:


public static void main(String[] args) {  Integer num1=new Integer(23);  Integer num2=new Integer(23);  if(num1==num2){  System.out.println("地址相等");  }else if(num1.equals(num2)){  System.out.println("值相等");  }  }
输出为:值相等

eqauls 与 = =之异同

1)比较方式角度:

= =是面向过程的操作符;equals是面向对象的操作符

= =不属于任何类,equals则是任何类(在Java中)的一个方法;

我们可以:

(1)Primitive1 (基本类型)= = Primitive2(基本类型);

(2)Object Reference1(对象引用)= = Object Reference2(对象引用)

(3)Object Reference1 (对象引用) .equals(Object Reference2 (对象引用))

这三种比较

但却不能Primitive1 (基本类型).equals( Primitive2(基本类型));

对于基本类型,没有面向对象中发送消息一说,自然也不会有

方法成员。


2)比较目的角度:

1) 如果要比较两个基本类型是否相等,请用= =;

2) 如果要比较两个对象引用是否相等,请用= =;

3) 如果要比较两个对象(逻辑上)是否一致,请用equals;

对两个对象(逻辑上)是否一致的阐释:

有人会问:在C++中, 比较两个对象相等不是也可以用==吗?我知道您是指运算符重载,但是很遗憾,Java中不支持运算符重载(java中亦有重载过运算符,他们是“+”,“+=”,不过也仅此两个,而且是内置实现的);所以,对象的是否相等的比较这份责任就交由 equals()来实现。

这个“逻辑上”其实就取决于人类的看法,实际开发中,就取决于用户的需求;

有人会有看法:“取决于人类的看法”太过宽泛和不严肃,如果某人要两件

风牛马不相及的事物也相等,equals是否也能作出这样的比较呢?我们说可以的

下面这个例子说明了这一点:



class Horse {  String Type;  int Legs;  //相等的标准:腿的数目相等  public boolean equals(Object o){  if(this.Legs==((Cattle)o).Legs){  return true;  }  return false;  }  public Horse(String Type,int legs){  this.Type=Type;  this.Legs=legs;  }   }  class Cattle  {  String Type;  int Legs;  //相等的标准:腿的数目相等  public Cattle(String Type,int legs){  this.Type=Type;  this.Legs=legs;  }  public boolean equals(Object o){  if(this.Legs==((Horse)o).Legs){  return true;  }  return false;  }  }  public class EqualsTest{  public static void main(String[] args)  {   Cattle c=new Cattle("I'm the Cattle",4);  Horse h=new Horse("I'm the Horse",4);  if(c.equals(h)){  System.out.println(c.Type);  System.out.println(h.Type);  System.out.println("Cattle Equals Horse");  }  }  } 输出结果:

"I'm the Cattle"

"I'm the Horse"

"Cattle Equals Horse"

您瞧瞧:牛果真等于了马,为何相等?因为我们定义的相等标准是:腿的数目相等;您会说:“这太滑稽”,是滑稽,可这是人类的看法,计算机可没有滑稽的概念,当然也没有“不滑稽”的概念,我们定义了什么相等标准,他就踏踏实实的为我们实现了;

所以说:相等标准(即需求)一定要定好,否则,滑稽的事可就多了

第三节:equals()缘起:

equals()是每个对象与生俱来的方法,因为所有类的最终基类就是Object(除去Object本身);而equals()是Object的方法之一。

我们不妨观察一下Object中equals()的source code:


public boolean equals(Object obj) {  return (this == obj);  }
注意 “return (this == obj)”

this与obj都是对象引用,而不是对象本身。所以equals()的缺省实现就是比较

对象引用是否一致;为何要如此实现呢?前面我们说过:对象是否相等,是由我们的需求决定的,世界上的类千奇百怪(当然,这些类都是我们根据模拟现实世界而创造的),虽然Object是他们共同的祖先,可他又怎能知道他的子孙类比较相等的标准呢?但是他明白,任何一个对象,自己总是等于自己的,何谓“自己总是等于自己”呢,又如何判断“自己总是等于自己”呢?一个对象在内存中只有一份,但他的引用却可以有无穷多个,“对象自己的引用1=对象自己的引用2”,不就能判断“自己总是等于自己”吗?所以缺省实现实现自然也就是

“return (this == obj)”;

而到了我们自己编写的类,对象相等的标准由我们确立,于是就不可避免的要覆写

继承而来的public boolean equals(Object obj);

如果您有过编覆写过equals()的经验(没有过也不要紧),请您思考一个问题:

“两个对象(逻辑上)是否一致”实际上是比较什么?没错,或许您已脱口而出:

就是对象的属性(即field,或称数据成员)的比较。方法是不可比较的哦。(这个问题是不是有些弱智呢?哈哈)

第四节:对一个推论的思考

推论如下:一言以蔽之:欲比较栈中数据是否相等,请用= =;

欲比较堆中数据是否相等,请用equals;

因为(根)基本类型,(根)对象引用都在栈中; 而对象本身在堆中;

这句话又对又不对,问题出在哪,就是“数据”二字,先看栈中,数据或为基本类型,或为对象引用,用==比较当然没错;但是堆中呢?对象不是堆中吗?不是应该用equals比较吗?可是,我们比较的是堆中“数据”,堆中有对象,对象由什么构成呢?可能是对象引用,可能是基本类型,或两者兼而有之。如果我们要比较他们,该用什么呢,用”equals()”?不对吧,只能是”= =”!所以正确的结论是:欲比较栈中数据是否相等,请用= =; 欲比较堆中数据是否相等,请用equals;

因为(根)基本类型,(根)对象引用都在栈中(所谓“根”,指未被任何其他对象所包含);而对象本身在堆中。


作者: 苏格拉底的弟子    时间: 2012-1-3 22:09
==操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量是否相等,只能用==操作符。如果一个变量指向的数据是对象类型的,那么,这时候涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如 Objet obj = new Object();变量obj是一个内存,newObject()是另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用==操作符进行比较。equals 方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。
作者: 沈样    时间: 2012-1-3 22:12
两个都是比较,==是比较内存地址,equals是比较内容
作者: 胡威    时间: 2012-1-4 09:12
区别1:==是等于运算符,比较两个变量值是否相等,不属于任何类,不被对象调用,equals则是任何类的一个与生俱来的方法,必须被对象调用;==既可以用于两个基本类型变量之间比较,也可以用于两个引用变量比较,而equals只用于两个引用变量之间的比较
区别2:当==和equals两边都是引用变量时,前者比较的是变量在栈内存中的值(也即所指向对象的地址值),后者比较的是两个引用变量指向的对象中的内容是否相同。因为可能出现两个引用变量指向的是不同对象,但是对象的内容是相同的,这是用==的结果是false,而用equals的结果是true





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