Java中的equals方法和clone方法

一.equals方法

Object中的equals方法用来检测一个对象是否等于另一个对象。在Object类中,这个方法将判断两个对象是否具有相同的引用。如果两个对象具有相同的引用,它们一定是相等的。这样看,将其作为默认操作也是合情合理的。然而,对于大多类来说,这种判断没有什么意义,所有我们常常需要重写equals方法。
下面是一个实现比较雇员对象是否相等的equals方法(一个雇员对象假设它有姓名,薪水,雇佣日期信息,如果这些信息都相同的话,就认为它们是相等的):

class Employee{
	private String name;
	private double salary;
	private Date hireDay;
	//...
	public boolean equals(Object otherObject){
		if(this == otherObject){
			return true;//如果两个对象相等,就直接返回true
		}
		if(otherObject == null){
			return false;//如果otherObject为空,则直接返回false
		}
		if(getClass() != otherObject.getClass()){
			return false;//只有两个对象数以同一类时,才有可能相等
		}
		//开始测试对象的域是否相等
		Employee other = (Employee) otherObject;
		return Objects.equals(name,other.name)
			&& salary = other.salary
			&& Other.equals(hireDay,other.hireDay);
		/*使用Other.equals(a,b)是为了防备name和hireDay可能为null的
		情况。当a,b都为空时,返回true,当只有一个为空时返回false。*/

在子类中定义equals方法时,首先调用超类的equals。如果检测失败,对象就不可能相等。如果超类中的所有域都相等,再比较子类中的域。
但是如果隐式和显式的参数不属于同一个类,这时候该如何定义equals呢?
在Java语言规范中要求equals方法应该遵循下面这些特性:
(1)自反性:对于任何非空引用x,x.equals(x)要求返回true;
(2)对称性:对于任何的引用x和y,x.equals(y)的结果和y.equals(x)的结果应该是一样的;
(3)传递性:对于任何引用x,y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true;
(4)一致性,如果equals中的对象没有发生变化,那么重复调用equals方法得到的结果应该是不变的;
(5)对于任何非空引用x,x.equals(null)应该返回false。
如何比较两个类是否属于同一个类?
(1)如果equals的语义在每个子类中有所改变,就使用getClass检测;
(2)如果所有的子类都有统一的语义,就使用instanceOf检测。
注意:如果重新定义equals方法,也需要重新定义hashCode方法。
当两个对象使用equals方法结果为true时,它们hashCode必须相等,但hashCode相等时,两个对象却不一定相等。

二.clone方法

当拷贝一个变量时,原始变量与拷贝变量引用同一对象。这就是说,改变一个变量的所引用的对象会对另一个对象产生影响。
默认的克隆操作是浅拷贝,它并没有克隆包含在对象中的内部对象。
如果要实现深拷贝,必须克隆所有可变的实例域:
下面是一个建立深拷贝的例子(还是上面那个雇员对象的例子):

class Employee implements Cloneable{
	// ...
	public Employee clone() throws CloneNotSupportedException{
		/*只要在clone中含有没有实现Cloneable接口的对象,clone方法就会抛出
	一个异常,虽然代码里的对象都实现了Clonable接口,但是编译器并不知情。
	并为了其他类可以使用该clone方法,将可见域改为public。*/
	Employee cloned = (Employee) super.clone();
	clone.hireDay = (Date) hireDay.clone();
	return cloned;
	}
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值