Effective Java 总结(二) 对于所有对象都通用的方法

在改写equals的时候请遵守通用约定

不改写equals方法时,每个实例只与自身相等,如果满足一下任意一个条件,则不需要改写equals方法:

  • 一个类的实例本质上都是唯一的
  • 不关心类是否支持“逻辑相等”功能
  • 超类已经改写了equals方法
  • 类是私有的,并且可以确定它的equals方法永远不会被调用

 

改写equals方法时,需要遵守的约定:

  • 自反性(自己和自己相等)
  • 对称性(x和y相等,反过来y也和x相等)
  • 传递性(x与y相等,y与z相等,则x与z相等)
  • 一致性(x与y相等,则不论进行多少次比较,结果都不会变)
  • 非空性(o.equals(null)一定返回false)

 

改写equals时总是要改写hashCode

改写一个类的equals方法后,两个不同的对象可能在逻辑上是相等的,但是根据Object的hashCode方法来看,它们仅仅是两个对象,没有其他共同的地方,因此hashCode方法返回的不会是两个相等的整数,这可能会导致一些问题。

如果你把一个对象放入Map中当作Key,此后你创建一个与原对象逻辑相等的新对象用作Key去取值,你会发现结果返回的是null

因此你应该针对对象间用来进行逻辑比较的值来确定hashCode,该值应该是获取hashCode表达式中的唯一变量。

 

总是要改写toString

这个不用多说了,对象如果不改写toString方法,会直接输出“类名@:hashCode”,为了方便调试,总是要改写对象的toString方法,eclipse/Myeclipse都提供这个方法。

一个改写toString方法的例子

public class Person {
	public String name;
	public boolean sex;
	public int age;
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", sex=" + sex + ", age=" + age + "]";
	}

}

 

谨慎地改写clone

按照书中的话来讲,能不重写clone就不要去重写,因为它带来的问题太多了。关于“深拷贝”和“浅拷贝”,可以转战这篇博客:【Java深入】深拷贝与浅拷贝详解,但这篇只提到了反序列化方法,其实还可以用反射和表达树来实现深拷贝。

书中是不建议自定义重写clone方法的,如果非要重写书中总结为一句话:clone方法就是一个构造器,你必须确保它不会伤害到原始的对象,并确保正确地创建被克隆对象中的约束条件。

还有一点是在别人博客上看到的,出处https://blog.csdn.net/wusd1256/article/details/80282015

查看Cloneable接口实际上可以发现里面什么方法都没有,clone方法却来自Object类,继承了Cloneable接口为什么就能重写clone方法了呢?原因在于clone方法在Object类中的修饰符是protected,而Cloneable接口和Object处于同一个包下,熟悉修饰符的都知道protected的权限限定在同一个包下或者其子类。Cloneable和Object同属于一个包,Cloneable自然能继承clone方法,继承了Cloneable接口的成为了它的子类同样也就继承了clone方法。

 

考虑实现Comparable接口

 

其实我感觉这点没什么可说的,就是实现Comparable接口中的compareTo方法,自己编写比较规则。

此外Arrays和Collections都已经提供了sort方法,而且如果需要在数组/集合内部定义排序规则,还可以新建一个Comparator实例,自己实现compare方法,再为数组或集合调用就好了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值