Object 简述
Object 类是 Java 中所有类的始祖, 在 Java 中每个类都是由它扩展而来的。
在 Java 中, 只有基本类型 ( primitive types) 不是对象, 例如,数值、 字符和布尔类型的值都不是对象。
所有的数组类塱,不管是对象数组还是基本类型的数组都扩展了 Object 类。
equals 方法
Object 类是 Java 中所有类的始祖, 在 Java 中每个类都是由它扩展而来的。
// Object 中的 equals 方法
public boolean equals(Object obj) {
return (this == obj);
}
1 Java 语言规范要求 equals 方法具有下面的特性:
1 ) 自反性: 对于任何非空引用 x, x.equals(x) 应该返回 true。
2 ) 对称性: 对于任何引用 x 和 y, 当且仅当 y.equals(x) 返回 true, x.equals(y) 也应该返回 true。
3 ) 传递性: 对于任何引用 x、 y 和 z, 如果 x.equals(y) 返 N true, y.equals(z) 返回 true,x.equals(z) 也应该返回 true。
4 ) 一致性: 如果 x 和 y 引用的对象没有发生变化,反复调用 x.eqimIS(y) 应该返回同样的结果。
5 ) 对于任意非空引用 x, x.equals(null) 应该返回 false,
2 使用 Class 还是使用 instanceof ?
•如果子类能够拥有自己的相等概念, 则对称性需求将强制采用 getClass 进行检测。
•如果由超类决定相等的概念,那么就可以使用 imtanceof进行检测, 这样可以在不同子类的对象之间进行相等的比较。
3 编写一个完美的 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.getCIassO) return false;
如果所有的子类都拥有统一的语义,就使用 instanceof 检测:
if (!(otherObject instanceof ClassName)) return false;
5 ) 将 otherObject 转换为相应的类类型变量:
ClassName other = (ClassName) otherObject
6 ) 现在开始对所有需要比较的域进行比较了。使用= 比较基本类型域,使用 equals 比较对象域。如果所有的域都匹配, 就返回 true; 否 则 返 回 false。
return fieldl == other.field && Objects.equa1s(fie1d2, other.field2)
如果在子类中重新定义 equals, 就要在其中包含调用 super.equals(other。)
提示:对于数组类型的域, 可以使用静态的 Arrays.equals 方法检测相应的数组元素是否相等
4 扩展:
java.util.Arrays
• static Boolean equals(type[] a , type[] b) 5.0
如果两个数组长度相同, 并且在对应的位置上数据元素也均相同, 将返回 true。 数组的元素类型可以是 Object、 int、 long、 short、 char、 byte、 boolean、 float 或 double 。
java.util.Objects
• static boolean equals(Object a, Object b)
如果 a 和 b 都为 null, 返回 true ; 如果只有其中之一为 null, 则返回 false ; 否 则 返 回a.equals(b)。
5 Demo:
public class Employee{
...
punlic boolean equals(Object otherObject){
// 1. 引用检测
if(this == otherObject) return true;
// 2. 检测参数 otherObject 是否为空
if(otherObject == null) return false;
// 3. 比较 this 与 otherObject 是否为同一类
if(getClass() != otherObject.getClass()) return false;
// 4. 将 otherObject 转换为相应的类型变量
Employee other = (Employee) otherObject;
// 5. 最后进行所有的域的比较
return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
}
...
}