第3章 对于所有对象都通用的方法
来源:互联网 发布:淘宝转化手机端链接 编辑:程序博客网 时间:2024/06/05 20:39
第8条:覆盖equals时请遵守通用约定
覆盖equals方法看起来似乎很简单,但是有许多覆盖方式会导致错误,并且后果非常严重。最容易避免这类问题的办法就是不覆盖equals方法,在这种情况下,
类的每个实例都只与它自身相等。如果满足了以下任何一个条件,这就正是所期望的结果:
类的每个实例本质上都是唯一的。对于代表活动实体而不是值(value)的类来说确实如此,例如Thread。Object提供的equals实现对于这些类来说正是正确的行为。
不关心是否提供了“逻辑相等”的测试功能。例如,java.util.Random覆盖了equals,以检查两个Random实例是否产生相同的随机数序列,但是设计者并不认为客户
需要或者期望这样的功能。在这样的情况下,从Object继承得到的equals实现已经足够了。
超类已经覆盖了equals,从超类继承过来的行为对于子类也是合适的。例如,大多数的Set实现都是从AbstractSet继承equals实现,List实现从AbstractList继承
equals实现,Map实现从AbstractMap继承equals实现。
类是私有的或是包级私有的,可以确定它的equals方法永远不会被调用。
在覆盖equals方法的时候,你必须要遵守它的通用约定。下面是约定的内容,来自Object的规范:
equals方法实现了等价关系:
自反性。对于任何非null的引用值x,x.equals(x)必须返回true。
对称性。对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true。
传递性。对于任何非null的引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也必须返回true。
一致性。对于任何非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致地返回true,或者一致地返回false。
对于任何非null的引用值x,x.equals(null)必须返回false。
结合所有这些要求,得出了以下实现高质量equals方法的诀窍。
1.使用==操作符检查“参数是否为这个对象的引用”。
2.使用instanceof操作符检查“参数是否为正确的类型”。
3.把参数转换成正确的类型
4.对于该类的每个“关键”域,检查参数中的域是否与该对象中对应的域相匹配。
5.当你编写完成了equals方法之后,应该问自己三个问题:它是否是对称的、传递的、一致的?
覆盖equals时总要覆盖hashCode
不要企图让equals方法过于只能
不要将equals声明中的Object对象替换为其他的类型
第9条:覆盖equals时总要覆盖hashCode
一个很常见的错误根源在于没有覆盖hashCode方法。在每个覆盖了equals方法的类中,也必须覆盖hashCode方法。如果不这样做的话,就会违反
Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常运作,这样的集合包括HashMap、HashSet和Hashtable。
下面是约定的内容,摘自Object规范:
在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一
地返回同一个整数。在同一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致。
如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果。
如果两个对象根据equals(Object)方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不一定要产生不同的整数结果。但是
程序员应该知道,给不相等的对象产生截然不同的整数结果,有可能提高散列表的性能。
第10条:始终要覆盖toString
第11条:谨慎地覆盖clone
Cloneable接口的目的是作为对象的一个mixin接口,表明这样的对象允许克隆(clone)。遗憾的是,它并没有成功地达到这个目的,其主要的缺陷在于,
它缺少一个clone方法,Object的clone方法是受保护的。如果不借助于反射,就不能仅仅因为一个对象实现了Cloneable,就可以调用clone方法。
即使是反反射调用也可能会失败,因为不能保证该对象一定具有可访问的clone方法。尽管存在这样那样的缺陷,这项设施仍然被广泛地使用着,因此
值得我们进一步地了解。
既然Cloneable并没有包含任何方法,那么它到底有什么作用呢?它决定了Object中受保护的clone方法实现的行为:如果一个类实现了Cloneable,Object
的clone方法就返回该对象的逐域拷贝,否则就会抛出CloneNotSupportedException异常。这是接口的一种极端非典型的用法,也不值得仿效。通常情况下,
实现接口是为了表明类可以它的客户做些什么。然而,对于Cloneable接口,它改变了超类中受保护的方法的行为。
如果实现Cloneable接口是要对某个类起到作用,类和它的所有超类都必须遵守一个相当复杂的、不可实施的,并且基本上没有文档说明的协议。由此得到一种
语言之外的机制:无需调用构造器就可以创建对象。
第12条:考虑实现Comparable接口
- 第3章 对于所有对象都通用的方法
- Effective Java读书笔记(第3章-对于所有对象都通用的方法)
- 《Effective Java》第3章 对于所有对象都通用的方法
- 对于所有对象都通用的方法
- 对于所有对象都通用的方法
- 对于所有方法都通用的对象
- 对于所有对象都通用的方法
- 对于所有对象都通用的方法
- 对于所有对象都通用的方法
- 对于所有对象都通用的方法
- EffectiveJava第三章:对于所有对象都通用的方法
- 第12条 对于所有对象都通用的方法——考虑实现Comparable接口
- Effective Java:对于所有的对象都通用的方法
- effective java(对于所有对象都通用的方法)
- Effective Java:对于所有对象都通用的方法
- 对于所有对象都通用的方法(二)
- Effective Java Note(对于所有对象都通用的方法)
- Effective Java:对于所有对象都通用的方法
- Ubuntu网路配置
- 互联网不确定性的传奇故事
- javascript函数参数
- UIDocumentInteractionController 的使用
- 论文档化和架构重要性
- 第3章 对于所有对象都通用的方法
- 短信、邮件群发平台
- linux (CentOS)安装python-tesseract 用于验证码识别
- (4.3.1.13.1) FragmentPagerAdapter刷新fragment最完美解决方案
- Android中的菜单-OptionMenu
- HttpClient4.4 模仿登陆及维持同一session 请求
- CXF-webservice使用记录
- 【转】
- Android中用get方式提交数据到服务器