相等测试与继承-equals

来源:互联网 发布:淘宝头像设计制作 编辑:程序博客网 时间:2024/06/05 02:58


**:(a.equals(b)a是隐式参数,b是显示参数)


Object类是Java中所有类的超集,每个类都是由它扩展而来的。
Object类中的equals方法用于检测一个对象是否等于另外一个对象。


1.先看看Obejct类中的equals方法的源码:
    public boolean equals(Object obj) {
        return (this == obj);
    }
天啊,居然这么简单。显然在这个方法中只做了是否引用同一个对象的判断。


Object obj1 = new Object();
Object obj2 = new Object();
显然这里的obj1 == obj2的结果为false,因为他们不是同一个对象。那么equals的结果当然也为false了。
这里的equals方法非常局限,只能判断变量是否引用同一个对象。




2.对于多数类来说,这样的判断没由什么意思。这时就需要重写equals方法。equals的判断机制分两种
情况:隐式和显示参数属于同一个类 or :隐式和显示参数不属于同一个类




a.隐式和显示参数属于同一个类


如果同属一个类的情况下,判断这两个对象相等:getClass判断是否属于同一个类


1.if (this == otherObject)
return true;//如果两个变量引用同一个对象,那么这两个变量一定相等。
2.this.age == other.age//对比对两个对象中的实例域和调用父类的equals对比父类中的实力域,如果都相等,那么就判定相等。


b.隐式和显示参数不属于同一个类:
如果隐式和显示参数不属于同一个类,equals方法将如何处理呢?这是一个很有争议的问题。在上面的例子中,使用getClass判断是否同属于一个类,如果发现类不匹配,equals就直接返回false。但是,许多人却喜欢用instanceof进行检测。
但是第二者的方式,容易招致一些麻烦。
if (!(otherObject instanceof Object
return false;
举例来说,这些麻烦发生在超类和子类中间。如果otherObject是Object类或者其子类,那么instanceof就会返回true。
但是,将显式参数和隐士参数换位的话,otherObject就会存在是Object类父类的可能性,那么instanceof就会返回false。这就导致了一个问题:a.equals(b) :true  b.equals(a):false
 这就违反了equals的对称性。(解决的办法是在(otherObject instanceof Object)中的Objet固定使用父类判断,那么所有的Object的子类都会通过这一层的判断。下面再具体分析这种情况。)




 !到底是使用getclass还是instanceof来检测,这要根据问题的情况:


 如果子类能够拥有自己的相等概念,则对称性需求将强制采用getclass。
如果有超类决定相等的概念,那么就可以使用instanceof,这样就可以在不同子类之间进行相等的比较。


我个人的理解:通俗的说就是,西瓜和香蕉都是水果,西瓜就是西瓜,香蕉就是香蕉,西瓜不可能是香蕉。那么就可以使用getclass。另外一种情况就是,项目经理和开发人员都是员工,一个经理可能是开发人员,开发人员也可能是经理,在员工中有内置的标识id,那么就可以用instanceof检测,如果都是员工,再根据超类中的id判断是否是同一个人。(这种情况下应该将超类的equals声明为final)


一下附上示例:


getclass:
public boolean equals(Object otherObject) {
if (this == otherObject)
return true;
if (otherObject == null)
return false;
if (getClass() != otherObject.getClass())
return false;
Student other = (Student) otherObject;
return this.schoolName.equals(other.schoolName) && super.equals(otherObject);
}
instanceof:
public final boolean equals(Object otherObject)
{
if (this == otherObject)
return true;
if (otherObject == null)
return false;
if (!(otherObject instanceof Person))
return false;
Person other = (Person ) otherObject;
return  this.id==(otherObject.id);
}



原创粉丝点击