标签:override 自己 hashtable bool ble 忠告 pre his blog
第八条:覆盖equals时请遵守通用约定
什么时候需要覆盖equals方法?类具有自己的逻辑相等概念,并且父类的equals方法不能满足需要。
重写equals时需要遵循一下约定:
自反性:不知道怎么写能让这个返回false,如果返回false了,那么把结果添加到Collection集合类中时,那么contains方法就会一直返回false
对称性:
class Fifth1 { private String s; public Fifth1(String s) { this.s = s; } @Override public boolean equals(Object o) { if (o instanceof Fifth1) { return s.equalsIgnoreCase(((Fifth1) o).s); } if (o instanceof String) { return s.equalsIgnoreCase((String) o); } return false; } }
Fifth1 fifth1 = new Fifth1("FZK"); String s = "fzk";
这两个比较就违反了自反性,fifth1.equals(s)调用自定义的equals方法,s.equals(fifth1)调用String的equals方法。
List<Fifth1> list = new ArrayList<Fifth1>(); list.add(fifth1); list.contains(s);
然后又有这种代码,结果可能是true,也可能抛运行时异常。
传递性:
class Point { private final int x; private final int y; public Point(int x, int y) { this.x = x; this.y = y; } @Override public boolean equals(Object obj) { if (!(obj instanceof Point)) return false; Point p = (Point) obj; return p.x == x && p.y == y; } } class ColorPoint extends Point { private final String color; public ColorPoint(int x, int y, String color) { super(x, y); this.color = color; } }
ColorPoint肯定需要一个equals。
@Override public boolean equals(Object obj) { if (obj instanceof ColorPoint) { return false; } return super.equals(obj) && ((ColorPoint)obj).color.equals(color); }
Point p = new Point(1, 1); ColorPoint colorPoint = new ColorPoint(1, 1, "red");
这两个比较会失去对称性。
这么写equals:
@Override public boolean equals(Object obj) { if (obj instanceof ColorPoint) { return false; } if (!(obj instanceof ColorPoint)) { return obj.equals(this); } // obj is a ColorPoint return super.equals(obj) && ((ColorPoint)obj).color.equals(color); }
Point p = new Point(1, 1);
ColorPoint colorPoint1 = new ColorPoint(1, 1, "red");
ColorPoint colorPoint2 = new ColorPoint(1, 1, "blue");
colorPoint1.equals(p);
colorPoint2.equals(p);
colorPoint1.equals(colorPoint2);
比较这三个的时候又会失去传递性。
其实上面的那种设计,没有什么特别好的办法。改变设计框架还能解决上面的问题,第一中办法是将Color作为ColorPoint的成员。另一种办法是将超类建成抽象类,只要不能直接实例花超类的实例,上面的问题就不会发生。
一致性:相等的永远相等,除非改变了什么。在比较的时候,不要使equals依赖不可靠的资源。
非空性:书的作者起的名,指所有的对象和null 比较的时候都不能返回true。还有在方法里不能返回NullpointerException。
在写完一个equals方法时一定要考虑是否是对称的,传递的,一致的。自反和非空通常会自动满足。
忠告:
第九条:覆盖equals时总要覆盖hashCode方法
如果覆盖了equals而没有覆盖hashCode,会违反Object.hashCode的通用约定,导致该类无法结合所有基于散列的集合一起正常运作,这样的集合包括HashMap,HashSet,HashTable。
Object规范:
第十条:始终要覆盖toString方法
第十一条:谨慎地覆盖clone
地十二条:考虑实现Comparable
书中太啰嗦,感觉没什么好说的。
Effective java -- 2 对于所有对象都通用到方法
标签:override 自己 hashtable bool ble 忠告 pre his blog
原文地址:http://www.cnblogs.com/badboyf/p/6283598.html