这一章主要讲解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. vue 移动端在div上绑定click事件 失效

    在.vue的文件中使用了better-scroll,在div标签上绑定click事件后,无效. 原因:使用了better-scroll,默认它会阻止touch事件.所以在配置中需要加上click: t ...

  2. 原生javascript实现二级延时菜单

    一.实现原理: 使用定时器和排他思想完成 二.代码: <!DOCTYPE html> <html> <head> <title></title&g ...

  3. ubuntu下报错Sub-process /usr/bin/dpkg returned an error code (1)的解决方法

    cd /var/lib/dpkg sudo mv info info.bak #即备份一个info sudo mkdir info #新建一个新的info目录 然后采用以下命令重装那些出错的软件包 s ...

  4. 使用Jenkins进行前端UVE项目部署

    操作步骤 1.用 Jenkins 管理员账号下载 NodeJS Plugin 2.系统管理 ---> 全局工具配置 ---> NodeJS ---> 安装 ---> 自动安装 ...

  5. Flask快速实现简单python接口

    Flask 是一个轻量级 web 框架,自由.灵活.可扩展性强.Flask 本身相当于一个内核,大部分功能都需要扩展第三方库. Flask 框架有多“轻量”呢,之前写过一篇 Django实现restf ...

  6. 从零开发一款txt小说下载器

    在日常开发中,列表是一个非常常用的一个东西,可以用listview和recyclerview实现.当然,由于recyclerview更为实用且强大,它也是更好的方案. 而我以前为了方便,习惯直接拿网上 ...

  7. http GET 和 POST 请求的优缺点和误区 --前端优化

    Get和Post在面试中一般都会问到,一般的区别:(1)post更安全(不会作为url的一部分,不会被缓存.保存在服务器日志.以及浏览器浏览记录中)(2)post发送的数据更大(get有url长度限制 ...

  8. vue学习笔记3: 动态绑定

    一.知识点 动态绑定: vue-class: 三目写法 对象写法 数组写法 vue-style: 三目写法 对象写法 数组写法 二.代码示例 1. vue-class vue-class三目写法 &l ...

  9. urllib基本用法(了解)

    一.urllib.urlopen 1.urlopen from urllib import request r = request.urlopen('http://www.baidu.com/') # ...

  10. 【java面试】数据库篇

    1.SQL语句分为哪几种? SQL语句主要可以划分为以下几类: DDL(Data Definition Language):数据定义语言,定义对数据库对象(库.表.列.索引)的操作. 包括:CREAT ...