一、equals方法
(一)、equals提供了实现等价关系
1、自反性:对于非null的引用值x,x.equals(x)返回true,所以重写equals是会写
public boolean equals(Object o) {
if (o == this)
return true;
....
}
2、对称性,如果x.equals(y)返回true,则y.equals(x)也返回true
package jdk.learn;
import java.sql.Timestamp;
import java.util.Date;
/**
* Created by yesh on 2015/4/6.
*/
public class TestTimestamp {
public static void main(String[] args) {
testEquals();
}
/***
* Timestamp违反了equals中的对称行,所以Timestamp类中
* 有个免责声明,不要将Date和Timestamp混用
* 输出结果:false,true
*/
public static void testEquals(){
Date date = new Date();
Timestamp timestamp = new Timestamp(date.getTime());
System.out.println(timestamp.equals(date));
System.out.println(date.equals(timestamp));
}
}
注:Timestamp违反了equals的原则,所以使用的时候要注意。
3、传递性,非null的x,y,z如果x.equals(y)和y.equals(z),则x.equals(z)。
4、一致性:相等的对象永远相等,不相等的对象永远不相等。
5、非空性:所有的对象都不能等于null
所以在重新equals的时候:
if(date==null){
return false;
}
if(date instanceof Date){ //使用instanceof就可以省掉判断null
return false;
}
注:使用给了instanceof 就不需要使用date==null的方式
(二)、注意点
1、当写完了equals方法后一定要判定,是否遵守这5个等价关系,如果没有就要进行修正。
2、要覆盖hashCode方法
不重写hashCode方法后,对进行equals是没有影响的,但是对使用Hash散列会出现预想不到的结果。
package jdk.learn;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* Created by yesh on 2015/4/6.
*/
public class TestHashCode {
public static void main(String[] args) {
Map map = new HashMap();
PhoneNumber phoneNumber = new PhoneNumber("123456789");
map.put(phoneNumber,"yezi");
System.out.println(map.get(phoneNumber)); //取出的值为null
PhoneNumber phoneNumber1 = new PhoneNumber("123456789");
System.out.println(phoneNumber.equals(phoneNumber1)); //输出true
}
static class PhoneNumber{
private String number;
public PhoneNumber(String number) {
this.number = number;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof PhoneNumber)){
return false;
}
PhoneNumber phoneNumber1 = (PhoneNumber)obj;
if(this.number==null&&this.number==null){
return true;
}
return this.number.equals(phoneNumber1.number);
}
@Override
public int hashCode() {
Random random = new Random();
int hashCode = random.nextInt(100);
return hashCode;
}
}
}
二、clone方法
1、clone的对象应该有super.clone获取,不应该使用new来创建。
在源码中BitSet的clone方法中获取:BitSet result = (BitSet) super.clone();后接着对内部的数据调用clone方式。
2、实现接口Cloneable
3、注意浅层复制和深层复制的关系。