对于不等于null的x、y、z,有以下规定:
自反性
x.equals(x)==true。
对称性
y.equals(x)==true <---> x.equals(y)==true。
传递性
x.equals(y)==true,y.equals(z)==true ---> x.equals(z)==true
一致性
对于不等于null的x和y,只要对象中,被equals操作使用的信息没有被修改,那么多次调用x.equals(y),要么一直返回true,要么一直返回false。
要想严格遵循这一条约定,必须保证equals方法里面不依赖外部不可靠的资源,如果equals方法里面依赖了外部的资源,就很难保证具有一致性了。
非空性
对于不等于null的x,x.equals(null)必须返回false。要遵守这个约定,只需要在equals里面加上这么一段代码 if(o == null) return false,然而,这样做往往是没有必要的,因为我们都会在equals方法的第一步,做instanceof校验,检查参数是否为正确的类型。而a.instanceOf(null)会返回false。
-
使用==检查参数是否为这个对象的引用,是,则直接返回true,提供判断的效率。
-
使用instanceof检查参数是否为正确的类型,如果不是,返回false。
-
把参数转成正确的类型。因为在第二步已经做了instanceof校验,所以能够确保这一步不会出错。
-
对于类中每一个关键的属性,也就是“逻辑相等”需要判断的属性,逐一比较参数的这些属性是否和对象的一致。比较时需要注意一下细节:
1) float和double类型的属性,要使用Float.compare(f1,f2)或者Double.compare(d1,d2)方法进行比较
2) 对象类型的属性,使用equals方法比较,有些属性可能为null,为了避免出现空指针异常,可以采用这样的方式:
(field ==null ? o.field == null : field.equlas(o.field))
3) 对于数组类型的属性,则要把这些原则用到每个元素上,如果每个元素都很重要,可以考虑使用Arrays.equals方法
4) 比较顺序会影响equals方法的性能,为了获得最佳的性能,应该最先比较最有可能不一致的属性或者开销最低的属性。
- 当你编写完equals方法后,请检查是否符合五条军规——自反、对称、传递、一致、非空,写单元测试校验!
网友评论