在Java中覆盖equals - getClass()方法

时间:2012-08-06 15:27:25

标签: java override equals equality

在帖子What issues should be considered when overriding equals and hashCode in Java?中,我们详细解释了如何使用getClass在Java中编写适当的相等方法来比较我们所等的两个对象的RUntime类型。我理解我们这样做的原因是为了确保如果B延伸A我们想要a.equals(b)= b.equals(a)(反身性)。

它确实提供了一个很大的局限性。如果你有一个对象集合A,那么它们是A的子类,那么a.equals(b)总是假的......或许,在某些时候,我们应该坚持旧的{{1}运算符提供多态性并允许子类型相等?你的想法是什么?

2 个答案:

答案 0 :(得分:4)

您只需要查看java.util即可查看重新定义.equals()的地方的示例,仅关注界面。例如,java.util.List,其中定义了相关的特征相等性,并且明确记录了计算哈希码的公式。

所以回答你的问题,是的 - 在某些情况下忽略子类型是有道理的。但我喜欢Josh Bloch通过使接口成为等价方面的方法。

答案 1 :(得分:1)

情况不一定如此。例如,如果查看JDK中的集合,它们会使用较不严格的相等定义。下面的代码输出“true”两次。最后,这是合同和文件的问题。

equals contract in List(强调我的):

  

将指定对象与此列表进行比较以获得相等性。当且仅当指定的对象也是列表时,返回true,两个列表具有相同的大小,并且两个列表中的所有对应元素对都相等。 (如果(e1 == null?e2 == null:e1.equals(e2)),则两个元素e1和e2相等。)换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等。 此定义确保equals方法在List接口的不同实现中正常工作。

请注意,只要所有实现List的类尊重该合同,它就不会违反反身性要求。

public static void main(String[] args) {
    List<String> list1 = new ArrayList<String>();
    list1.add("a");

    List<String> list2 = new LinkedList<String>();
    list2.add("a");

    List<String> list3 = Arrays.asList("a");

    System.out.println("arraylist = linkedlist? " + list1.equals(list2));
    System.out.println("arraylist = Arrays.aslit? " + list1.equals(list3));
}