java语言规范要求equals的特性:
1)自反性:对于任何非空引用x,x.equals(x)应返还true。
2)对称性:对于任何x,y,x.equals(y)与y.equals(x) 返回值相同。
3)传递性:对于任何引用x,y,z,若x.equals(y),y.equals(z)则x.equals(z)
4)一致性:如果x和y引用的对象没有发生变化,则反复调用x.equals(y)的结果应一致。
5)对于任何非空引用x,x.equals(null)应返回false
equals方法是判断对象是否相等的方法。在Object类中,这个方法判断两个对象是否具有相同的引用。如果具有相同的引用则相等,否则不相等。但是这在实际使用中却没有太大意义。一般使用中是判断两个对象是否具有相同的状态,以此来判断对象是否相等。
如:Empolyee员工类的例子,需要测试name、age是否相等:
class Employee{ protected String name; protected int age; @Override public boolean equals(Object obj){ if(this == obj) return true; if(obj == null) return false; if(getClass() != obj.getClass()) return false; Employee other = (Employee)obj; return name.equals(other.name)&&(age==other.age); } }
子类中定义equals方法时,首先调用父类的equals方法,若检测失败,对象就不肯能相等;若父类中域相等,则需继续检测子类的实力域。
class Manager extends Employee{ private String level; @Override public boolean equals(Object obj){ if(!super.equals(obj)) return false; Manager other = (Manager)obj; return level.equals(other.level); } }
继承中的相等测试:
当equals参数不属于同一类时,且具有继承关系时,instanceof的检测结果将不满足对称性。
如:c是p的子类,如果在equals中用instanceof检测,那么:
p.equals(c) 将返回true;
c.equals(p) 将返回false或者抛出异常。
编写equals方法的建议:
1、显示参数命名为otherObject,稍后强制转换为叫other的变量。
2、检测this==otherObject
3、检测this==null
4、检测getClass()!=otherObject.getClass()
如果所有的子类都拥有统一的语义,就使用instanceof检测
otherObject instanceof ClassName
5、将otherObject转换为相应类型的变量
6、比较所有的域
7、若在子类中重新定义了equals方法,则需在子类中包含调用super.equals(other)
5、