Effectivie Java 第二章读书笔记

EffectiveJava笔记 第二章通用方法
1.覆盖equalsshi需要遵守的约定
i:首先来确认一下什么情况下不需要重写equals方法
a:类的实例本质上都是唯一的
b:不关心类是否提供了逻辑相等的实例
c:超类已经覆盖了equals,从父类继承来的对与子类也是合适的
d:类是私有的或者是包级私有的,介意确定的是它的equals方法永远不会被用到。(这种情况下无疑是应该覆盖这个类,一面被访问到,重写抛出异常即可)
ii:需要覆盖的情况:
a:类有自己的逻辑相等,且超类没有覆盖equals(值类)
注意:实例受控的类,比如枚举类型,逻辑相等和值在意义上是等同的
iii:实现equals方法的约束条件
a:自反性:对于任何非null的引用值,x.equals(x)必需返回TRUE
b:对称性:对于任何非null的引用值,当且仅当x.equals(y)返回TRUE时y.equals(x)返回TRUE。
例如:区分大小写的字符串和普通字符串比较,反过来就不行,所以应该在equals判断是否为相同类型
c:传递性:对于任何非null的引用值x,y,z,如果x.equals(y),y.equals(z)都返回TRUE,那么x.equals(z)返回TRUE
一个超类和两个子类的情况
d:一致性:对于任何非null的引用值x,y,只要对象的所有信息没有被修改那么多次调用就会返回一直的结果。
不可变对象需要注意:相等的对象永远相等,不相等的对象永远不相等。
e:对于任何非null的引用值,x.equals(null)必需返回false
在equals显式的和null比较是不必要的,因为instanceof 已经进行了类型比较
注意:面向对象的等价关系基本问题:无法既增加新的组件,又保留equals约定,解决这类问题的基本思路是使用复合。
iv:高质量编写equals方法的诀窍
a:使用==操作符来检查是否是这个对象本身的引用(一般对象之间比较代价比较昂贵会使用这种方法比较)
b:使用instanceof 操作符检查参数类型是否正确
c:把参数类型转换成正确的类型
d:对于关键域要进行参数检查
float以及double使用对应的Compare进行比较,其他基本类型使用==操作符,并且要注意比较顺序(比较代价高的放在后边)
f:编写完成好,要看是否实现对称,传递,一致
v:注意的一些方法
a:覆盖equals方法总得覆盖hashCode方法(否则在散列集合中才能正常运行,比如hashMap)散列集合中的对象属性改变之后无法移除,因为equals变化之后hashCode比较出现问题
b:不要想将equals方法写的太过于智能
c:不要将equals声明中的Object对象替换为其他的类型
2.覆盖equals方法的时候总要覆盖hashCode方法
我感觉去思考一下散列集合的实现,然后这个就能理解的更加清楚
i:为不相等的对象产生不不相等的散列码(可以提高查找性能)
a:把某个非零的常数值比如说17,保存在一个名为result的int值类型的常量中
b:为每一个关键域计算int类型的散列码c
boolean:f?1:0
byte,char,short,int: (int)f
long:(int)(f^(f>>>32))
float:Float.floatToBits(f)
double:Double.doubleToLongBits(f),得到long然后long再转换成int
对象:递归的调用对象的hashCode
数组:把每个元素作为单独的域来处理
c:把b中的散列码合并到result reuslt=31*reuslt+c
d:返回result
e:验证相等的实例是否有相等的散列码
ii:排除equals比较计算中没有用到的任何域,
iii:可以缓存散列码
iv:不要试图排除掉对象的关键部分来提高性能
3.始终覆盖toString
使用printf,print,z字符串联操作符(+)以及assert或者调试打印,toString会自动被调用。这里让我想起thinking in java 里边的一个死循环,就是在toString里边这样写 “String”+this 会出现无限递归调用
4.谨慎地覆盖clone
cloneable接口表明对象允许克隆,但是这个接口没有提供克隆方法,Object提供了受保护的clone,不通过反射机制是无法调用的,有时即使使用了反射也不一定调用成功
从上边的话只能说明cloneable改变了超类中受保护clone方法的行为,
i:clone方法的一般的约定
a:x.clone!=x true
b:x.clone.equals(x) true
c:x.clone().equals(x)
5.考虑使用Comparable接口
compareTo方法没有在Object类里边声明,它是Comparable接口的唯一方法,不仅能够进行等同性比较还能执行顺序比较。
类在不同类型接口的等同性测试有的依赖equals,有的依赖compareTo,
compareTo和equals的区别:
a:compare的实例化参数是泛型而非Object
b:compare的比较是为了排序不是等同性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值