参考资料:《practical Java》
***************************************************************************************************************************************************************************************
在上一篇《Java 学习笔记——字符串》里面提到了String类的equals方法,而StringBuffer类中又没有equals方法的实现,那么在平时使用过程中该如何使用equals方法来做相等判断呢?
Java所有的类都直接或间接继承在Object类,而在Object类里面实现了equals()方法如下:
public boolean equals(Object obj) {
return (this == obj);
}
从上面的代码可以看到,这个equals方法就是将两个对象的引用地址进行比较,这是等同于"=="操作符的,显然我们使用equals方法的初衷不是这样的,那么之所以会出现这样的结果,是因为很多类都没有对equals方法进行重写,当然Java API里面还是有不少重写了equals方法,具体在使用时可以查看官方文档。但用户自己设计的类肯定是没有实现equals方法的。这里总结一下它的实现方法。
***************************************************************************************************************************************************************************************
1.如果比较双方指向同一个对象,则直接返回true
boolean equals(Object obj){
if(obj == this){
return true;
}
...
}
2.一般只建议同类对象之间进行equals比较,这里使用getClass方法来判断运行时对象是否是同类对象,另外这里还要防止对null的对象执行getClass操作
if((obj != null) && getClass() == obj.getClass()){
...
}
3.如果上面两个条件都满足则填充具体的比较条件,根据不同类实现不一样。
综合上面三点,就可得到一个普遍使用的equals方法,示例代码如下:
//定义一个汽车类,如果汽车的制造年份与品牌一样,则认为两辆汽车相等。
public class Car { private String madeYear; private String type; public Car(String madeYear, String type){ this.madeYear = madeYear; this.type = type; } public void driver(){ System.out.print("Is moving"); } public boolean equals(Object obj){ if(obj == this){ return true; } if(obj != null && getClass() == obj.getClass()){ Car c = (Car)obj; if((madeYear == c.madeYear) && (type == c.type)){ return true; } } return false; } }
Car c1 = new Car("1999", "宝来"); Car c2 = new Car("1999", "宝来"); System.out.println(c1.equals(c2));
运行上面这段代码,输出true
*************************************************************************************************************************************************************************************
上面实现了一般情况下对于equals的使用,那么如果某个类的equals比较的属性不能完全满足我要求,而类又无法重写时该如何实现呢?这时候就需要重新定义一个新的类继承原先的类,然后加入一些新的属性,然后重新实现equals方法。比如上面的汽车类,如果我要求对颜色也进行比较以进一步区分不同的车,那么就需要使用这种方法。在这里生产年份和品牌在父类里面已经提供了比较,那么在新的子类里面就可以通过调用super.equals方法来实现它们的比较,而不需要再重写一遍。具体见示例代码:
// 新加一个类MyCar
public class MyCar extends Car { private String color; public MyCar(String madeYear, String type, String color) { super(madeYear, type); this.color = color; } public boolean equals(Object obj){ if(obj == this){ return true; } if(obj != null && getClass() == obj.getClass() && super.equals(obj)){ MyCar m = (MyCar)obj; if(color == m.color){ return true; } } return false; } }
MyCar c1 = new MyCar("1999", "宝来", "红色"); MyCar c2 = new MyCar("1999", "宝来", "红色"); System.out.println(c1.equals(c2));
运行上面的代码将输出true
***************************************************************************************************************************************************************************************
有些时候还需要与基类进行比较,这种情况这里不再讨论。