(8):覆盖equals请遵循通用约定

再覆盖equals方法是,你应该遵循它的通用约定,下面是约定内容:

自反性(reflexive):对于任何非null的引用值x,x.equals(x)必须返回true。 
如果违背,当你把该类的实例添加到集合(collection)中,然后该集合的contains会告诉你,没有包含你刚刚添加的实例。 

对称性(symmetric):对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true。 

public final class CaseInsensitiveString {  
    private final String s;  
  
    public CaseInsensitiveString(String s) {  
        if (s == null)  
            throw new NullPointerException();  
        this.s = s;  
    }  
  
    // Broken - violates symmetry!  
    @Override public boolean equals(Object o) {  
        if (o instanceof CaseInsensitiveString)  
            return s.equalsIgnoreCase(  
                ((CaseInsensitiveString) o).s);  
        if (o instanceof String)  // One-way interoperability!  
            return s.equalsIgnoreCase((String) o);  
        return false;  
    }  
  
    //This version is correct.  
//   @Override public boolean equals(Object o) {  
//       return o instanceof CaseInsensitiveString &&  
//           ((CaseInsensitiveString) o).s.equalsIgnoreCase(s);  
//   }  
  
    public static void main(String[] args) {  
        CaseInsensitiveString cis = new CaseInsensitiveString("Polish");  
        String s = "polish";  
        System.out.println(cis.equals(s) + "  " + s.equals(cis));  
    }  
}  

这个例子就违反了这条约定,当我们使用CaseInsensitiveString所重写的equals方法是是忽略大小写的,但反过来string去调用它的equals方法是区分大小写的,所以这就造成比较不对称。正确的做法应该去除与string互操的那段代码。


传递性(transitive):对于任何非null的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也必须返回true。

书上例子太长了,不写了。


一致性(consistent):对于任何非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致的返回true,或者一致的返回false。 
都不要是equals方法依赖于不可靠的资源。 


非空性(Non-nullity):对于任何非null的引用值x,x.equals(null)必须返回false。 


高质量equals方法: 
1、使用==操作符检查“参数是否为这个对象的引用”。 
2、使用instanceof操作符检查“参数是否为正确的类型”。 
3、把参数转换成正确的类型。 
4、对于该类的每个“关键(significant)”域,检查参数中的域是否与该对象中对应的域相匹配。 
这点myeclipse自动生成的并不完全完美,myeclipse生成如下: 
else if (!name.equals(other.name)) 
return false; 
但是,这条是要求你改成: 
else if (name != other.name && !name.equals(other.name)) 
return false; 
5、当你编写完成了equals方法之后,应该会问自己三个问题:他是否的对称的、传递的、一致的。 
(覆盖equals时总要覆盖hashcode;不要企图让equals方法过于智能;不要将equals声明中的Object对象替换为其他的类型。) 




尽量不要省略@Override。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值