effectjava中object类中的几个方法小结

本章说的就是Object类,因为它是所有类的超类。而所谓的“object类中对所有对象都通用的方法”,就是指它里面的非final方法(equals,hashcode,tostring,clone)。

10、覆盖equals方法时需要遵守的通用约定

非必要请不要覆盖equals方法,因为equals本来的职责就是判断类实例是否相等,它不应该被赋予额外太多职责。那什么时候该覆盖equals方法呢? 一个例子就是值类情形,值类就比如Integer,String这些类。它们有自己特有的“逻辑相等”条件,而且超类没有覆盖equals。我们使用值类时希望的是比较它们的值是否相等,而不是关系它们是否是同一个对象。 但实例受控的值类不需要覆盖equals方法,因为它们每个值最多只存在一个对象。就比如枚举类型,对于这样的类,逻辑相同和对象相同是一个意思。

另外在覆盖equals时,必须遵循以下5条约定:
(1)自反性:x != null 的情况下, x.equals(x) 必须返回true
(2)对称性:x,y 都不为null,那么如果y.equals(x) == true ,则x.equals(y) 也肯定是true
(3)传递性:x,y,z都不为null,那么如果x.equals(y), y.equals(z) 都为true,则x.equals(z)也肯定得是true
(4)一致性:x,y都不为null,且x,y对象都没有修改过,那么多次比较下来,x.equals(y)还是返回同样的结果
(5)与null相比,永远返回false:x != null, 则x.equals(null) == false;
总结:这一节内容主要还是想说,你如果重写了equals方法,那么你要考虑的事就比较多了,你写的equals要满足上面说的那5个原则。

11、覆盖equals时总是要覆盖hashcode

在每个重写了equals方法的类中,都必须重写hashcode方法。在符合规范的情况下,hashcode的通用约定可以总结为以下几点:(1)equals判断相同的对象,hashcode相同。(2)如果通过equals比较不相等的两对象,其分别的hashcode不一定非得不一样。(就是说equals判断为不同的对象,其hashcode却相等,在特定情况下也算是符合规范的)
总结:重写了equals后就必须要重写hashcode,否则你的程序将会出现异常。

12、始终覆盖tostring

默认的tostring方法返回的信息,不是很适合开发人员查看。好的tostring重写应该包含对象中所有值得关注的信息。将它设计的简洁,美观即可。

13、谨慎的覆盖clone

首先需要明确,虽然Cloneable接口表明了这样的对象是允许克隆的,但它本身并没有clone方法,而需要借助Object中的clone方法。当一个类声明Cloneable后,Object中的clone方法就返回该对象的逐域拷贝。在使用clone的时候,务必要小心的就是,对于基本数据类型或不可变对象,直接调用super.clone也许没有问题,但对于可变对象,直接clone出来的对象中的可变域的引用和原对象中的将是同一个,即它们的修改会互相影响,这个问题可以通过递归的使用clone来解决,见下图),但如果该可变对象的引用,还套了一层引用,比如那个可变对象是个map,那么对于map中的每个值,在clone时,都需要进行单独的clone才行,这操作也叫深拷贝。要注意的是,final域是无法被clone时赋新值的。
在这里插入图片描述
简言之,所有实现cloneable的类都应该覆盖clone方法,并且它的返回类型是返回该类本身的。然后clone方法应该先调用super.clone方法,然后再修正任何需要修改的地方。作者建议除了数组外,其他少用clone功能,而是选择拷贝构造器。 拷贝构造器的意义例如:我有一个hashset:s ,并希望把它拷贝成一个treeset,可以使用new Treeset<>(s)来实现。这个 Treeset<>(s) 就是一个“拷贝构造器”。

14、考虑实现Compareable接口

类实现compareable接口,就表明它的实例具有内在的排序关系。其中在进行域值比较时,避免使用<,>操作符,而应该在装箱基本类型的类中使用静态的compare方法,或在Comparator中使用比较器构造方法。在这里插入图片描述

总结:如果要重写equals方法那么就必须重写hashcode方法,看书看的云里雾里,不太好理解,但是作者的意思反正就是你重写了这两个方法,那你就要好好考虑到上面那5项原则,在你重写的方法中要符合那几项规范,这看起来蛮麻烦的,要考虑的问题还是挺多的额。。。不太建议随意重写那两个方法。
然后clone方法主要是处理好深拷贝,这大部分人都知道,然后作者建议使用拷贝构造器来实现克隆为好,除了数组外其他少用clone功能。
至于Compareable接口,反正实现它后你肯定会重写compareTo方法嘛,这里建议使用比较器构造来做比较吧

END

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值