在 Java 中有这样一个类 ,它是所有类 的祖先,任何类 都是其子孙类 ,它就是 java.lang.Object ,如果一个类 没有显式地指明其父类 ,那么它的父类 就是 Object 。如同我们称自己为炎黄子孙一样,所有的类 都可以称为 Object 子孙, ^_^ 。在 java 中除了基本型别 ( 数字、字符、布尔值, primitive type) 不是对象之外,其它的均为对象 (class type) 。那么,这个 Object 到底给我们留下了什么“遗产”呢?下面将从最基本的讲起:
1. public boolean equals (Object obj).
所有的类 均可以按照自己的需要对 equals 方法进行覆盖,顾名思义,这个方法可用来比较两个对象是否“相等”,至于什么才叫“相等”,各个类 可以根据自己的情况与需要自行定义。例如 String ,就是要求两个对象所代表的字符串值相等,而对于一个雇员类 (Employee) ,则可能是要求姓名、年龄、工资等一样才算是“相等”。尽管不同的类 有不同的规则,但是有一条规则却是公用的,它就是:如果两个对象是“一样” (identical) 的,那么它们必然是“相等” (equals) 的。那么什么才叫“一样”?如果 a==b ,我们就说 a 和 b 是“一样的”,即 a 和 b 指向 (refer to) 同一个对象。 Object 类 中的 equals 方法实施的就是这一条比较原则,对任意非空的指引值 a 和 b ,当且仅当 a 和 b 指向同一个对象时才返回 true 。
打开 JDK5.0 的帮助文档,我们会看到 equals 方法必须满足一系列性质:
A .自反性,即对任意一个非空的指引值 x , x.equals(x) 永远返回 true ;
B .对称性,对任意非空的指引值 x 和 y ,当且仅当 x.equals(y) 返回 true 时 y.equals(x) 返回 true ;
C .传递性,当 x.equals(y) 返回 true 并且 y.equals(z) 返回 true 时, x.equals(z) 也返回 true ;
D .一致性,对任何非空的指引值 x 和 y ,只要 x 和 y 所指向 (refer to) 的对象没有发生变化,那么 x.equals(y) 的结果也不会变化;
E .对任意非空的指引值 x , x.equals(null) 应该返回 false 。
如何才能打造一个“完美”的 equals 方法呢,下面时 JavaCore 给出的建议:
第一步:把显式参数声明为 otherObject( 这个看个人喜好,不一定非得叫 otherObject ,至于什么叫显式参数什么叫隐式参数我就不赘术了 )
第二步:检查待比较得两个值是否指向同一个对象 (identical) ,就是用 == 进行比较,这是一个比较偷懒的步骤,如果那两个东东都一样了,就不用再比了。
第三步:测试 otherObject 是否为 null ,如果是则返回 false
第四步:用 getClass() 方法或者 instance of 关键字对 otherObject 进行测试,主要是看待比较的两个 reference 是否指向同一个 class type 或者 otherObject 是否指向隐式参数所属的类 或子类
第五步:通过第四步的测试后,就可以进行强制类型转换了,把 otherObject 强制转换成与隐式参数相同的类型
第六步:根据自己的业务逻辑和需要定义什么时候才是 equal ,如对所有的域进行比较,如果全部相同就返回 true ,否则返回 false
2. public int hashCode ()
每个类 都可以复写 Object 类 中的 hashCode 方法, Object 类 中的 hashCode 方法就是简单
地将对象在内存中的地址转换成 int 返回。这样,如果一个类 没有复写 hashCode 方法,那么它的 hashCode 方法就是简单地返回对象在内存中的地址。在 JDK 中,对 hashCode 也定义了一系列约束,其中有一条就是如果两个对象是“ equal ”的,那么它们的 hashCode 方法返回的整数值必须相同,但是如果两个对象是“ unequal ”,那么 hashCode 方法的返回值不一定必须不同。正因为这个约束,我们如果复写了 equals() 方法,一般也要复写 hashCode 方法。
3
.public String toString
()
toString 方法是一个从字面上就容易理解的方法,它的功能是得到一个能够代表该对象的一个字符串, Object 类 中的 toString 方法就是得到这样的一个字符串: this.getClass().getName() + '@' + Integer.toHexString(hashCode()) ,各个类 可以根据自己的实际情况对其进行改写,通常的格式是类 名 [field1=value1,field2=value2……fieldn=valuen] 。 Core 上面说这个方法对于写日志非常有用,暂时还没试过:)。