1 重写equals方法时请遵守通用约定

(1)无需覆盖equals方法的情况

  • 要求独一无二
  • 不要求逻辑相等
  • 超类已经覆盖equals方法,对其子类也适用
  • 一个类是私有的或者是包私有(可以重写后抛出异常,防止被重写)

(2)重写equals方法要保持等价关系

  • 自反性:对于任意非空引用值x,x.equals(x)必须返回true。
  • 对称性:对于任意非空引用值x和y,x.equals(y)必须返回true,当且仅当y.equals(x)返回true。
  • 传递性:对于任意非空引用值x,y,z,如果x.equals(y)返回true而且y.equals(z)也返回true,那么x.equals(z)必须返回true。
  • 一致性:对于任意非空引用值x和y,只要equals方法中使用的信息没有被修改,那么不管多少次调用x.equals(y)都必须一致性地返回true或者false。
  • 对于任意非空引用值x,x.equals(null)必须返回false。

注:重写equals方法需要打破等价关系是不被允许的。

2 重写equals方法都要重写hashCode方法

(1)equals与hashCode的关系

  • equals相等,hashCode必须相等。
  • equals不等,hashCode可以相等,也可以不等。
  • hashCode不等,equals一定不等。

(2)重写原则

  • 不要为了提高性能而试图在哈希码的计算过程中将重要的属性排除掉:防止大量hash冲突
  • 不要为hashCode返回的值提供详细的规范:为了未来拓展

3 始终重写toString方法

(1)重写原则

  • toString方法应该返回类里面所有有用的信息
  • 无论我们是否决定要指明格式,我们都应该清晰地在文档中表达我们的意图

(2)DEMO

  • 指定格式:程序员自行补充注释和格式
/**
* Returns the string representation of this phone number.
* The string consists of twelve characters whose format is
* "XXX-YYY-ZZZZ", where XXX is the area code, YYY is the
* prefix, and ZZZZ is the line number. Each of the capital
* letters represents a single decimal digit. *
* If any of the three parts of this phone number is too small
* to fill up its field, the field is padded with leading zeros.
* For example, if the value of the line number is 123, the last
* four characters of the string representation will be "0123".
*/
@Override
public String toString() {
return String.format("%03d-%03d-%04d",areaCode, prefix, lineNum);
}
  • 不指定格式:通过IDE或者Google AutoValue来自动生成

4 谨慎重写clone方法

(1)重写clone方法

  • 子类需要继承Cloneable接口,否则调用Object的clone方法将抛出CloneNotSupportedException。
  • 如果一个类实现了Cloneable接口,Object的clone方法将返回一个属性逐一拷贝的对象,否则它就抛出一个CloneNotSupportedException异常。
  • 一个类含有引用属性,需要进行深度克隆
public class Stack implement Cloneable{
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
this.elements = new Object[DEFAULT_INITIAL_CAPACITY];
} public void push(Object e) {
ensureCapacity();
elements[size++] = e;
} public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null;
} private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
} @Override
public Stack clone() {
try {
Stack result = (Stack) super.clone();
result.elements = elements.clone(); // 引用属性进行深度克隆
return result;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}

5 考虑实现Comparable或使用Comparator

  • 一个对象在与指定的对象比较顺序时,当该对象小于,等于或者大于指定的对象时,相应地返回一个负的整型值,0或者正的整型值。
  • 若指定对象的类型不能与发起比较的对象进行比较,则抛出ClassCastException异常。
  • 具有自反性,对称性和传递性。
  • 强烈建议(x.compareTo(y) == 0) == (x.equals(y))成立(非绝对,比如:BigDecimal类)
  • compareTo方法中的基本数据类型比较,避免使用+ - > < 运算符,应该使用包装类的比较方法,如:Double.compare。(+ - 可能导致溢出)
  • Comparator示例:
private static final Comparator<PhoneNumber> COMPARATOR =
comparingInt((PhoneNumber pn) -> pn.areaCode)
.thenComparingInt(pn -> pn.prefix)
.thenComparingInt(pn -> pn.lineNum); public int compareTo(PhoneNumber pn) {
return COMPARATOR.compare(this, pn);
}

Effective Java 读书笔记(二):对象通用方法的更多相关文章

  1. Java 读书笔记 (二) 对象和类

    Java 作为一种面向对象语言,支持以下基本概念: 多态 继承 封闭 抽象 类 对象 实例 方法 重载 对象: 是类的一个实例,有状态和行为.以人为例,黄种人.白种人.黑种人为类,每一个具体的人为类的 ...

  2. 《Effective Java》读书笔记二(通用方法)

    No8 覆盖equals方法时请遵守通用约定 通用约定,下面的约定前提都是x/y/z不为null值. 自反性(reflexive),x.equals(x)必须返回true. 对称性(symmetric ...

  3. [Effective Java 读书笔记] 第7章 方法

    第39条 必要时进行保护性拷贝 对于可变类,如果作为参数传入到自己的类里,并作为自己类的数据使用存储时,需要进行保护性拷贝,比如Date是可变的,如果传入一个Date类,最好做一个保护性拷贝,以免在调 ...

  4. 《Effective Java》笔记45-56:通用程序设计

    将局部变量的作用域最小化,可以增强代码的可读性和可维护性,并降低出错的可能性. 要使用局部变量的作用域最小化,最有力的方法就是在第一次使用它的地方才声明,不要过早的声明. 局部变量的作用域从它被声明的 ...

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

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

  6. Effective Java 读书笔记(一):使用静态工厂方法代替构造器

    这是Effective Java第2章提出的第一条建议: 考虑用静态工厂方法代替构造器 此处的静态工厂方法并不是设计模式,主要指static修饰的静态方法,关于static的说明可以参考之前的博文&l ...

  7. Effective java读书笔记

    2015年进步很小,看的书也不是很多,感觉自己都要废了,2016是沉淀的一年,在这一年中要不断学习.看书,努力提升自己 计在16年要看12本书,主要涉及java基础.Spring研究.java并发.J ...

  8. java读书笔记二

    这是我的一些读书笔记: 我研究了一下面向对象: 面向对象符合人类看待事物的一般规律,对象的方法的实现细节是包装的,只有对象方法的实现者了解细节 我觉得面向过程是由过程.步骤.函数组成,过程是核心,面向 ...

  9. Effective Java读书笔记完结啦

    Effective Java是一本经典的书, 很实用的Java进阶读物, 提供了各个方面的best practices. 最近终于做完了Effective Java的读书笔记, 发布出来与大家共享. ...

  10. Effective java 读书笔记(2)

    第四条:通过私有构造器强化不可实例化的能力 有时可能需要编写只包含静态方法和静态域的类,这样的工具类不希望被实例化,因为实例化对它来说没有意义. 然而,在缺少显式构造器的情况下,系统会自动提供一个缺省 ...

随机推荐

  1. 亚马逊AWS服务器CentOS/Linux系统Shell安装Nginx及配置自启动

    领了一个亚马逊的1年免费服务器,今天尝试安装 Nginx 服务器,使用原生的 Shell 方法. 为了方便以后查看,就把过程记录一下. 注意:亚马逊(AWS)服务器默认只能用 user-ec2 账户进 ...

  2. 调用微信公众平台扫一扫示例及解决接口报错 { "errMsg": "config:invalid signature" }

    一.解决报错问题 单从报错信息 invalid signature 就可以看出是 签名signature 有问题, 查了很多资料,终于知道了问题点, 后台让我直接调接口是不对的,签名是根据请求接口的页 ...

  3. ios 新建app iphone 、 ipad or universal ?

    很久没有关注这个新建app的  时候 选什么的问题了, 因为我们一般在公司 都是 已经建立好的app 直接 在那上面开发. 所以很久不建立新app 遇到新的app需要你自己去创建的时候 可能就会 有突 ...

  4. 复习Android布局

    效果如图: 这里没有做逻辑的处理,仅仅是布局的罗列.包括垂直和水平的线性布局,以及一个滚动的view. <?xml version="1.0" encoding=" ...

  5. SQL-W3School-函数:SQL AVG() 函数

    ylbtech-SQL-W3School-函数:SQL AVG() 函数 1.返回顶部 1. 定义和用法 AVG 函数返回数值列的平均值.NULL 值不包括在计算中. SQL AVG() 语法 SEL ...

  6. osgOcean编译

    E:\Visual Studio 2015\install\VC>e: E:\Visual Studio 2015\install\VC>E:\Visual Studio 2015\ins ...

  7. 置BAT批处理窗口显示颜色

    置BAT批处理窗口显示颜色 摘自:https://blog.csdn.net/tp7309/article/details/53450131 2016年12月04日 01:08:33 亦游 阅读数:1 ...

  8. 自定义string类

    #include <iostream> #include <cstring> using namespace std; class String; class Data{ // ...

  9. 解决Jmeter跨线程组取参数值难题!(还没试)

    来源 https://mp.weixin.qq.com/s/q7ArxwnX1sOfa9tfHouSBQ 如果你工作中已经在用jmeter做接口测试,或性能测试了,你可能会遇到一个麻烦.   那就是j ...

  10. 通过命令行给 XenServer 打补丁

    安装 XenCenter 客户端,cmd 到 XenCenter 安装目录. 1.上传补丁到服务器,获得uuid xe patch-upload -s <服务器IP地址> -u root ...