(1)关键技术剖析:(Object类的这三个方法)
v equals方法:比较两个对象是否相等,结果为boolean型。
v hashCode方法:获得两个对象的hash码,结果为int型。
v Clone方法:克隆当前对象,结果为Object型。
class T {
int a;
public T(int a) {
super();
this.a = a;
}
public static void main(String[] args) {
T a = new T();
T a1 = new T();
System.out.println("equals:"+a.equals(a1));
System.out.println(a==a1);
System.out.println("两个对象的hashCode:"+a.hashCode()+"***"+a1.hashCode());
System.out.println("两个对象的toString:"+a.toString()+"***"+a1.toString());
}
}
程序输出:
equals:false
false
两个对象的hashCode:1641745***11077203
两个对象的toString:T@190d11***T@a90653
² 如果两个对象的值相等的,人们往往会认为它们是Equals的,然而,从程序结果可以看出,执行a.equals(a1)得到的结果却是false。
² 同样,人们也希望两个值相等的hashCode也是相等的,然而从运行结果上看,它们的hashCode值并不相等。
之所以出现上述这些情况,是因为Object类的这些方法都是基于对象的地址实现的,对象a和b的值虽然一样,都是它们的地址不一样,就出现了上述这些情况。
因此,为了更好地设计一个类,开发人员最好自己定义equals()、hashcode()和clone方法,以方便人们更好的使用这个类。需要对T类进行改进,重写以上三个方法。
class T implements Cloneable{
int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public T(int a) {
super();
this.a = a;
}
@Override
// 根据现有对象克隆一个新对象,新对象和现有对象的值一样
protected Object clone() throws CloneNotSupportedException {
//克隆新对象时,应该先调用父类的克隆方法
T newObject = (T) super.clone();
newObject.setA(this.a);
return newObject;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + a;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
T other = (T) obj;
if (a != other.a)
return false;
return true;
}
@Override
public String toString() {
return "T[a=" + a + "]";
}
public static void main(String[] args) {
T a = new T(1);
T a1 = new T(1);
System.out.println("equals:"+a.equals(a1));
System.out.println(a==a1);
System.out.println("两个对象的hashCode:"+a.hashCode()+"***"+a1.hashCode());
System.out.println("两个对象的toString:"+a.toString()+"***"+a1.toString());
try {
System.out.println("clone:"+a.clone().toString()+"***"+a1.clone());
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
程序输出:(T类添加了equals()、clone()和hashCode())
false
两个对象的hashCode:32***32
两个对象的toString:T[a=1]***T[a=1]
clone:T[a=1]***T[a=1]
(2)源码分析:
² 实现equals()方法时,需要先判断现有对象和传入对象是否属于同一类,不是的话结果为false,是的话再比较对象的每个属性。如果所有属性都相等,就可以认为这两个对象就是相等的,结果为true。
² 实现hashCode()方法的思路是:先找到一个能够代表对象的键,与数据库中数据表的主键一样(一个主键代表数据表中的一条记录)。如果这个键是int型的,就可以直接返回键作为该多想的hashCode,如果是其他类型,就用键的hashCode作为对象的hashCode。
² 如果要使自定义的类能够被clone,必须实现cloneable接口并且重写它的clone方法,如果仅仅重写了clone方法而没有在类的声明中添加实现cloneable接口,那么在调用clone方法时将会出现cloneNotSupportException异常。实现clone方法时,先调用父类的clone方法,再将现有的属性值赋值给新对象。