Object:所有类的超类
Object类是Java中所有类的超类,在Java中每个类都是由它扩展来的。
尽管Object是一个具体的类,但是设计它主要是为了扩展。它所有的非final方法(equals、hasCode、toString、clone和fanalize)都有明确的通用约定(general contract),因为它们被设计成是要被覆盖(Override)的.
equals
Object类中的equals方法用于检测一个对象是否等于另外一个对象。在Object类中,这个方法将判断两个对象是否具有相同的引用。
然而,对于多数类来说,这种判断并没有什么意义。因为当判断对象是否相等时,经常需要检测两个对象状态的相等性。
通用约定 [JavaSE6]
- 自反性。对于任何非null的引用值x,x.equals(x)必须返回true。
- 对称性。对于任何非null的引用值x和y,如果y.equals(x)返回true时,x.equals(y)必须返回true。
- 传递性。对于任何非null的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)返回true时,x.equals(z)也必须返回true。
- 一致性。对于任何非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致地返回true,或者一致的返回false。
- 对于任何非null的引用值x,x.equals(null)必须返回false。
实现高质量equals的诀窍
- 1)显示参数命名为otherObject,稍后需要将它转换成另一个叫做other的变量。
- 2)使用==操作符检测this与otherObject是否引用同一个对象:
if(this == otherObject) return true;
- 3)检测otherObject是否为null,如果为null,返回false。这项检测时必要的。
if(otherObject == null) return false;
- 4)比较this与otherObject是否属于同于一个类。
如果equals的语义在每个子类中有所改变,就使用getClass检测:if(getClass() != otherObject.getClass()) return false;
如果所有的子类都拥有统一的语义,就使用instanceof检测:if(!(otherObject instanceof ClassName)) return false;
- 5)将otherObject转换为相应的类类型变量:
ClassName other == (ClassName) otherObject
- 6)现在开始对所有需要比较的域进行必较了。使用==比较基本类型域,使用equals比较对象域。如果所有的域都匹配,就返回true;否则返回false。
return field1 == other.field1&&Objects.equals(field2, other.field2)&&···;
- 7)如果在子类中重新定义equals,就要在其中包含super.equals(other)。
for example
class Employee
{
public boolean equals(Object otherObject)
{
//a quick test tot see if the objects are identical
if(this == otherObject) return true;
//must return false if the explicit parameter is null
if(otherObject == null) return false;
//if the classes don't match, they can't be equal
if(getClass() != otherObejct.getClass())
return false;
//now we know otherObject is non-null Employee
Employee other = (Employee) otherObject;
//test whether the fields have identical values
return name.equals(other.name)
&& salary == other.salary
&& hireDay.equals(other.hireDay);
}
}
class Manager extends Employee
{
public boolean equals(Obejct otherObject)
{
if(!super.equals(otherObject))
return false;
//super.equals checked that this and otherObject belong to the same class
Manager other = (Manager) otherObject;
return bonus == other.bonus;
}
}
告诫
- 覆盖equals时总要覆盖hashCode。
- 不要企图让equals方法过于智能。
- 不要将equals声明中的Object对象替换为其他的类型。(否则就没有覆盖Object.equals.)
未完待续
参考《Java核心技术》、《Effective Java》