论坛首页 Java企业应用论坛

equals方法最佳实践

浏览 1846 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (6) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-04-11   最后修改:2009-04-11
最近在看一本很基础的java书,对equals方法有了进一步的认识。
对于覆盖equals时要覆盖hashCode这里就不写了,这里只讨论equals
package employee;

public class Employee {
	
	private String name;

	public Employee(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public boolean equals(Object obj) {

		if(null == obj) return false;
	         if(!(obj instanceof Employee)) return false;
		Employee other = (Employee)obj;
		return name.equals(other.name);
	}

}

根据<<effective java中文版>>第二版的建议,这样写还算完美。
后来又有了一个类来增加了一些扩展:
package employee;

public class HorlyEmployee extends Employee {

	private int hours;
	
	public HorlyEmployee(String name,int hours) {
		super(name);
		this.hours = hours;
		
	}

	public int getHours() {
		return hours;
	}

	public void setHours(int hours) {
		this.hours = hours;
	}

}


来做一下测试:
public class Test {

	public static void main(String[] args) {
		
		Employee e = new Employee("jack");
		HorlyEmployee he = new HorlyEmployee("jack",5);
		
		System.out.println(e.equals(he));
		System.out.println(he.equals(e));
		
	}

}

结果为:
true
true

但是HorlyEmployee 类也想要自己比较准确的equals方法。hours属性也要进行比较,所以HorlyEmployee 也覆写equals方法,现在HorlyEmployee 类为:
package employee;

public class HorlyEmployee extends Employee {

	private int hours;
	
	public HorlyEmployee(String name,int hours) {
		super(name);
		this.hours = hours;
		
	}

	public int getHours() {
		return hours;
	}

	public void setHours(int hours) {
		this.hours = hours;
	}

	
	@Override
	public boolean equals(Object obj) {

		if(null == obj) return false;
		if(!(obj instanceof HorlyEmployee)) return false;
		HorlyEmployee other = (HorlyEmployee)obj;
		return super.equals(other)&&this.hours == other.hours;
	}
}

现在在来测试:
package employee;

public class Test {


	public static void main(String[] args) {
		
                  HorlyEmployee he = new HorlyEmployee("jack",5);
		HorlyEmployee he2 = new HorlyEmployee("jack",5);
		Employee e2 = new Employee("jack");
		System.out.println(he.equals(he2));
		System.out.println(he2.equals(he));
		
		}

}


结果为:
true
true

但是这样测试呢:
package employee;

public class Test {

	
	public static void main(String[] args) {
		
		Employee e = new Employee("jack");
		HorlyEmployee he = new HorlyEmployee("jack",5);
		System.out.println(e.equals(he));
		System.out.println(he.equals(e));
		
	}

}


结果为:
true
false

明显违返了equals方法的对称性原则。
就因为这个原因是,所以我看的这本书的作者推荐的覆写equals为:
将Employee中的这一行
if(!(obj instanceof Employee)) return false;

和HorlyEmployee 中的这一行
if(!(obj instanceof HorlyEmployee)) return false;

都换成:
if(this.getClass() != obj.getClass()) return false;

这样就不会出现这个问题。

就是这个原因,这本书的作者不推荐用instanceof 而是用 getClass()
原因如下:
有A,B两个类 B extends A 那么有:
a instanceof A 为true  (小写的为对应对象的实例)
b instanceof A 为true 而 a instanceof B 为 false
a1.getClass() == a2.getClass() 为true
a.getClass() == b.getClass() 为false

不知道大家有什么看法?
我看的这本书为<<Absolute Java>>2005年版。





论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics