对于所有对象都通用的方法 - 覆盖equals时请遵守通用约定

知识点:

1.哪些情况下不需要覆盖equals方法。

2.什么情况下需要覆盖equals方法。

3.覆盖equals方法需要遵守的约定。

4.写equals方法的诀窍。

5.写equals方法的告诫。

6.Java类库中的equals方法。


Java Object对象的九个方法。他们分别是clone(), getClass(), toString(), equals(), wait(), hashcode(), notify(), notifyall(), finalize()。这章讨论equals(), hashcode(), toString(), clone() 四个方法和Comparable接口。


1.哪些情况下不需要覆盖equals方法。

a.类的每个实例本质上都是唯一的。比如Thread。它们不是代表值的类,也不需要做值上的比较。

b.不关心类的对象是否逻辑相等。

c.超类已经重写了equals方法,子类用着也比较合适。

d.类是私有的或是包级私有的,我解释一下这两个概念, 看下面代码:类In就是私有的,只有类One内部可以访问,类Two就是包级私有的,前面没有任何修饰符,同一个包间恶意访问。这种不对外部开放的类,如果确定equals方法不会被调用,可以不重写。当然如果不想让他们被调用,也可以重写,调用的时候抛异常。

public class One{  
    private class In {
        
    }
}

class Two {

}

2.什么情况下需要覆盖equals方法。

很简单,类是值类,比如Integer, Date, Float等,对于他们对象的比较,我是想比较他们的值,并不是想知道这两个对象是不是同一个对象,就需要重写。


3.覆盖equals方法需要遵守的约定。

a.自反性

b.对称性

c.传递性

d.一致性

e.非null性

这五个特性的理解可自行看书,不作过多解释。


4.写equals方法的诀窍。

我们不可能按照第三条的五个约定来重写equals方法,这根本没法下手,按照下面诀窍来写,写完可以按照用上面五个约定来验证你的equals方法是否完美。

a.使用==操作符检查“参数是否为这个对象的引用”。如果是,返回true。如果引用都是一样,值肯定也是一样。

b.使用instanceOf操作符检查“参数是否为正确的类型”。如果不是,返回false。如果两个都不是同样类型的对象,值肯定不一样,不过两个对象实现同一个接口,我们应该判断参数是否为同一样的接口。

c.参数转换为正确的类型。

d.每一个关键域进行比较,全部相等则返回true。


5.写equals方法的告诫。

下面三个问题,我们在写的时候要注意:

a.覆盖equals时总要覆盖hashCode。我本身认为这条不是一定需要的,如果你的对象不会作为Map等类型的key,只有比较的功能,也可以不覆盖。但你要保证别人不会用这个类来作为Map的Key。如果别人这样做了,就会有问题。(我后面会详细讲解Map相关的知识)

b.不要把equals方法弄的过与复杂。其实就是简单的对象比较,不要把什么对象都弄来比较。

c.不要将equals神明中的Object对象替换为其它对象。那样就不是重写了,是重载了。


6.Java类库中的equals方法。

这里我们只看三个类,Object, String和Integer。看下面代码,Object的equals方法就是比较引用是不是一样。Integer的是,先看对象是不是Integer类,然后比较他们的值是否相等。String的是,先看对象的引用是不是一样,然后看对象类型是不是String,然后一个个字符比较。基本就是按照上面写equals方法的诀窍来写的。大家工作中碰到可以按照这种方式来写。

Object的equals方法
public boolean equals(Object obj) {  
      return (this == obj);  
} 

Integer的equals方法
public boolean equals(Object obj) {  
   if (obj instanceof Integer) {  
       return value == ((Integer)obj).intValue();  
   }  
   return false;  
}  

String的equals方法
public boolean equals(Object anObject) {  
        if (this == anObject) {  
            return true;  
        }  
        if (anObject instanceof String) {  
            String anotherString = (String) anObject;  
            int n = value.length;  
            if (n == anotherString.value.length) {  
                char v1[] = value;  
                char v2[] = anotherString.value;  
                int i = 0;  
                while (n-- != 0) {  
                    if (v1[i] != v2[i])  
                            return false;  
                    i++;  
                }  
                return true;  
            }  
        }  
        return false;  
    }  





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值