java的equals、hashcode和Clone方法

时间:2022-01-29 16:18:37

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类的这些方法都是基于对象的地址实现的,对象ab的值虽然一样,都是它们的地址不一样,就出现了上述这些情况。

因此,为了更好地设计一个类,开发人员最好自己定义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方法,再将现有的属性值赋值给新对象。