《Effective Java》:对于所有对象都通用的方法

本系列皆为读书笔记,“好记性不如烂笔头”,勤看,也要勤记录。此篇读书笔记来自《Effective Java》。

尽管Object是一个具体类,但设计它主要是为了扩展。它所有的非final方法都有明确的通用规定。任何一个类,在覆盖这些方法的时候,都有责任去遵守这些通用规定,如果不能做到这一点,其他依赖于这些规定的类就无法结合该类一起正常运作。 

第八条: 覆盖equals 时请遵守通用规定 
如果类具有自己特有的逻辑相等概念(不同于对象等同的概念),而且超类还没有覆盖equals以实现期望的行为,这时就需要覆盖equals方法。在覆盖时,需要遵守下面的通用约定; 
1.自反性   x.equals(x)必须返回true 
2.对称性   y.equals(x)返回true时,x.equals(y)必须返回true 
3.传递性   如果x.equals(y)返回true,y.equals(z)返回true, 那么x.equals(z)返回true 
4.一致性   只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致返回true,或者一致返回false 
5.对于非null的引用值x,x.equals(null)必须返回false。 

下面是实现高质量equals方法的诀窍: 
1.使用==操作符检查“参数是否为这个对象的引用”。 
2.使用instanceof操作符检查“参数是否为正确的类型”。 
3.把参数转换成正确的类型。 
4.对于该类中的每个“关键”域,检查参数中的域是否与该对象中对应的域相匹配。 
5.当你编写完成了equals方法,应该检查是否是对称的、传递的、一致的。 
6.不要企图让equals方法过于智能 
7.不要将equals声明中的Object对象替换成其他的类型 
8.覆盖equals方法时总要覆盖hashCode 

第九条:覆盖equals时总要 覆盖hashCode  
如果不覆盖hashCode,将导致该类无法结合所有基于散列的集合一起正常工作,比如:HashMap,HashSet,Hashtable 
下面是约定的内容; 
1.在应用程序执行期间,只要对象的equals方法的比较操作符所用的信息没有被修改,那么对同一个对象调用多次,hashCode方法都必须返回一个整数。在一个程序的多次执行过程中,可以不一致。 
2.如果两个对象根据equals方法比较是相等的,那么调用这两个对象的任何一个hashCode方法都必须产生同样的整数结果 
3.如果两个对象不相等,他们的hashCode方法不一定产生不同的整数结果。但是,给不相等的对象产生不同的整数结果,有可能提高散列表的性能。 

第十条:始终要 覆盖toString  
虽然Object提供了toString的一个实现,但返回的字符串通常不是用户期望看到的。它包含类的名称,以及一个“@“,接着就是散列吗的无符号十六进制表示法。当对象被传递给println或者被调试器打印出来时,toString方法会被自动调用。提供好的toString方法,不仅有利于这个类的实例,同样也有益于包含这些实例的引用的对象。 
在实现toString时,你可以决定是否在文档中指定返回值的格式。这样增强可读性,但一旦指定,就必须始终如一的坚持。所以无论是否指定格式,都应该在文档中明确的表明你的意图。 

第十一条:谨慎的 覆盖clone  
Cloneable接口的目的是作为对象的一个mixin接口,表明这样的对象允许克隆。但它缺少一个clone方法,Object的clone方法是受保护的。如果不借用反射,就不能达到调用clone方法的目的。既然Cloneable并没有包含任何方法,那么它到底有什么作用呢? 
如果一个类实现了Cloneable,那么Object的clone方法就返回该对象的逐域拷贝,否则就抛出异常。因此,该类必须遵守一个复杂的,不可实施的协议。由此得到一种语言之外的机制:无需调用构造器就可创建对象。 
实际上,clone方法就是另一个构造器,但必须确保他不会伤害原始的对象,并确保正确的创建被克隆对象中的约束条件。 
总之,所有实现了Cloneable接口的类都应该用一个公有的方法覆盖clone。该方法先调用super.clone,然后修正任何需要修正的域。一般情况下,这意味着要拷贝任何包含内部”深层结构“的可变对象,并用指向新对象的引用代替原来指向这些对象的引用。 

第十二条:考虑 实现Comparable接口  
compareTo方法并没有在Object中声明,相反,它是Comparable接口中唯一的方法。compareTo方法不但允许进行简单的等同性比较,而且允许执行顺序比较。类实现了Comparable接口就表明它的实例具有内在的排序关系。实现排序就这么简单: 
Arrays.sort(a); 
如果你正在编写一个值类,它具有非常明显的内在排序关系,比如按字母排序、按数值排序或者按年代排序,那你就应该坚决考虑实现这个接口。当该对象小于、等于、大于指定对象的时候,分别返回一个负整数、0、正整数。如果没法进行比较,抛出异常。 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值