5

为什么认为在 Java 中使用默认Objectequals方法并对其进行修改以使其适用于特定类(通过instanceof使用类型转换进行验证和使用)会更好:

public boolean equals(Object otherObject)
{
   boolean isEqual = false;

   if ((otherObject != null) && (otherObject instanceof myClass))
      {
         myClass classObject = (myClass)otherObject;

         if (.....) //checking if equal
         {
            .....
}

equals而不是用特定于每个需要使用的类的新方法重载它equals

public boolean equals(myClass classObject)
4

4 回答 4

8

的签名Object.equals()public boolean equals(Object)。如果您定义一个方法public boolean equals(MyClass),您将添加一个具有不同签名的新方法,而不是覆盖(或重新定义,如果您愿意)该Object.equals()方法。

由于所有集合都调用该Object.equals()方法,因此除了您自己的代码之外,任何人都不会调用您的新方法,因此几乎没有用处。例如,如果您创建 a Set<MyClass>,它将认为两个实例是不同的,尽管您的equals(MyClass)方法认为它们是相等的。

于 2012-11-25T16:17:19.463 回答
1

这是因为 Java 中的大多数类(列表、队列、地图等)都使用该boolean equals(Object obj)方法。在九十年代设计 Java 的时候,泛型还不存在。

使用例如Comparatoror的比较方法Comparable已更新为支持泛型,因此直接采用正确的类型(避免使用instanceof)。Object.equals()只需要一个通用的Object.

如果您.equals()使用新签名重载,其他集合将不知道您的新equals()方法,并且仍会调用由 提供的旧原始方法Object,因此您必须坚持使用instanceof. 请记住,重载与覆盖没有相同的效果。在覆盖子类方法时被调用,因为它具有完全相同的签名。在重载中,您只是提供具有不同签名的替代功能,因此调用者必须知道它。

或者,equals()您可以不使用该方法,而是稍微更改代码以使用带有泛型的较新比较方法。大多数集合已更新以支持泛型等ComparatorComparable

于 2012-11-25T16:26:16.323 回答
0

如果你这样做public boolean equals(MyClass classObject),你就会超载
所以你的方法不会被调用,因为它不会覆盖
你可以创建这样的方法,但你也需要equal(Object)为了让一切正常运行(集合等)。

您对这种方法感兴趣的唯一原因是性能。但我不认为现在你有使用问题equals(Object)

于 2012-11-25T16:17:51.257 回答
0

你必须为你的类重写 equals 方法。当你重写一个方法时,你不能改变方法参数,不能改变返回类型,也不能使方法的可访问性更受限制。

于 2012-11-25T16:19:25.127 回答