这一章主要讲解Object类中的方法, Object类是所有类的父类,所以它的方法也称得上是所有对象都通用的方法

第八条 覆盖equals时需要遵守的约定

Object中的equals实现,就是直接对对象进行相等的比较:

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

那么什么时候需要覆盖equals呢?

当你的类有自己的逻辑相等,而不是对象相等时,应该自己实现equals,比如Date和Interger,他们的相等比较不仅是对象相等,需要涉及到内部值的相等,

// Integer的equals实现:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
// Date的equals实现:
public boolean equals(Object obj) {
return obj instanceof Date && getTime() == ((Date) obj).getTime();
}

equals方法的实现必须满足等价关系(温习一下数学基本概念):

1.自反性。对于任何非null的引用值x,x.equals(x) 必须为true

2.对称性。对于非null的x和y,x.equals(y)推导出y.equals(x)

3.传递性。非null的xyz,x.equals(y) 并且y.equals(z),那么x.equals(z)

这里讨论了一个典型例子。自类扩展了父类,增加了新的值组件(变量),那么equals很难在父类子类之间同时生效,比如父类的equals就缺少子类的新增变量的比较,子类的equals来比较父类,父类缺少子类新增的变量。

文中提出了一种方法,基于组合优先于继承的原则,将子类独立出来,增加自己的值组件,并在子类中实现父类的实例,这样可以同时用equals比较这两部分

4.一致性。任何非null的xy,只要equals的比较操作在对象中所用的信息没有改变,多少次操作得到的值应该一样

5.非空性。一般并不需要在equals里显示的检查null == obj,因为 if (obj instanceof Integer) {}已经做了这个工作

关于写equals的几个建议:

1.优先使用==检查是否为这个对象的引用

2.使用instanceof检查参数是否为正确类型

3.equals覆盖时总要覆盖hashcode(),见第九条

4.不要让equals太智能太复杂

5.不要讲equals的参数改为其他类型,应该为Object

第九条 覆盖equals时总要覆盖hashCode

集合的操作都是基于散列的,比如从hashmap get 元素,先通过hashcode获取散列码,通过散列码找到对应的散列桶((hash bucket),然后在散列桶中通过equals找打对应的对象

所以,如果对象有同样的equals值,他们的hashcode应该也是相等的(Object规范 JAVA SE6);

反过来,有同样的hashCode,他们的eqauls值不一定要相同!

在计算散列码的过程中,如果equals中没有用到的域(比如成员变量),hashCode中也最好不要!

书中讲了一些简单的方法来获取hashCode,对于Integer,就是返回int value,boolean返回1或者0,我们看一下String的源码:

    public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}

String类会将string转换为value这样一个数(private final char value[])
所以就是对数组的每一个元素进行处理,最后获取到散列值组合

[Effective Java 读书笔记] 第三章 对所有对象都通用的方法 第八 ---- 九条的更多相关文章

  1. Effective Java读书笔记——第三章 对于全部对象都通用的方法

    第8条:覆盖equals时请遵守通用的约定 设计Object类的目的就是用来覆盖的,它全部的非final方法都是用来被覆盖的(equals.hashcode.clone.finalize)都有通用约定 ...

  2. [Effective Java 读书笔记] 第三章 对所有对象都通用的方法 第十---十一条

    第十条 始终覆盖toString() toString的实现可以使类使用起来更加舒适,在执行println等方法时打印出定制信息. 一单实现了自己的toString,指定输出的固定格式,在方法的文档说 ...

  3. [Java读书笔记] Effective Java(Third Edition) 第 3 章 对于所有对象都通用的方法

    第 10 条:覆盖equals时请遵守通用约定 在不覆盖equals方法下,类的每个实例都只与它自身相等. 类的每个实例本质上都是唯一的. 类不需要提供一个”逻辑相等(logical equality ...

  4. [Effective Java]第三章 对所有对象都通用的方法

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. [Effective Java 读书笔记] 第三章类和接口 第二十三-- ??条

    第二十三条 请不要再新代码中使用原生态类型 1 使用原生态类型,就失去了泛型在安全性和表述性方面的所有优势,所以新代码中不要使用原生态类型 2 List<String>可以传递给List作 ...

  6. [Effective Java 读书笔记] 第三章类和接口 第二十-二十一条

    第二十条 用函数对象表示策略 函数指针(JAVA的函数指针,是指使用对象的引用来作为参数,传递给另一个对象的方法)主要用来实现策略模式,为了在JAVA中实现这种模式,要申明一个接口来表示该策略,并为每 ...

  7. [Effective Java 读书笔记] 第三章类和接口 第十三 -- 十四条

    第十三条 使类和成员的可访问性最小化 总得来说,我们应该尽量将成员的访问范围限制到最小!有利于解耦,开发.测试和优化都能够更加独立. 对于成员(域,方法,嵌套类和嵌套接口),有四种可能的访问级别,访问 ...

  8. [Effective Java 读书笔记] 第三章类和接口 第十八--十九条

    十八条 接口优于抽象类 接口的特点: 1.一个类可以实现多个接口,不能继承多个类(抽象类) 2.接口不能有具体的方法实现,只定义标准类型 骨架类: 即实现一个abstract类来实现接口,提供给其他类 ...

  9. [Effective Java 读书笔记] 第三章类和接口 第十六条

    第十六条 复合优先于继承 如果不确定B和A的关系是,is-a的关系,B确实也是A,那么久不应该使用B继承A,否则会暴露实现细节, 你的实现都会限制在原始的实现上. 书中举的第一个例子,实现了一个类ex ...

随机推荐

  1. 【转】ArcGIS ADF 实时轨迹问题初步解决方案

    Web ADF 实时轨迹是指在Web客户端指定一资源项,并对资源项进行实进跟踪并绘制出轨迹图.实时绘制可采用Ajax实现服务端与客户端无刷新动态绘制,在.net2.0 框架下可轻易实现:通过客户端时钟 ...

  2. 探究Dubbo的拓展机制: 下

    承接上篇, 本篇博文的主题就是认认真真捋一捋, 看一下 Dubbo是如何实现他的IOC / AOP / 以及Dubbo SPI这个拓展点的 总览: 本篇的话总体上分成两部分进行展开 第一点就是 Dub ...

  3. Mybatis Plugin 以及Druid Filer 改写SQL

    背景 工作中偶尔会碰到需要统一修改SQL的情况,例如有以下表结构: CREATE TABLE `test_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, ` ...

  4. 我与Git的那些破事系列(下)--分支模型

    在上篇文章中,我提到了Git的基本概念和一些本人实际项目中的总结.然而,最近读了一片Vincent Driessen写的一篇文章,觉得他总结的太好了,忍不住站在他的肩膀上写一篇自己的理解.文章的连接放 ...

  5. spring boot 集成apollo 快速指南

    目前市面上流行的三大配置中心框架:Spring CLoud Config .Alibaba Nacos 以及携程apollo, 我们相应架构组号召,就使用Apollo吧. Work Flow 简单解释 ...

  6. Nmap使用教程(一)

    基本扫描技术 扫描单个网络 nmap 192.168.1.1/www.baidu.com 扫描多个网络/目标 nmap 192.168.1.1 192.168.1.2 #将扫描同个网段内不同的ip地址 ...

  7. 第二阶段冲刺个人任务——seven

    今日任务: 整体运行测试上传到公网上的程序. 昨日成果: 搭建网络服务器,上传数据库及程序.

  8. .NET Core Install for Ubuntu 14.04

      Add the dotnet apt-get feed In order to install .NET Core on Ubuntu or Linux Mint, you need to fir ...

  9. Linux 常用工具openssh之ssh-copy-id

    前言 ssh-copy-id命令可以把本地主机的公钥复制到远程主机的authorized_keys文件上,ssh-copy-id命令也会给远程主机的用户主目录(home)和~/.ssh, 和~/.ss ...

  10. springIOC源码接口分析(五):ListableBeanFactory

    一 继承关系 该接口是对BeanFactory的扩展,允许预加载bean定义的BeanFactory可以实现此接口 其目的在于使实现它的BeanFactory能够枚举所有的Bean 该接口不支持分层结 ...