为什么 String 类中的 equals 方法定义为 equals(Object anObject) 而不是 equals(String anObject)?

问题描述

这是来自equals()班的String

public boolean equals(Object anObject)
{
    if (this == anObject)
    {
        return true;
    }
    else
    {
        if (anObject instanceof String)
        {
            String aString = (String) anObject;
            if (this.coder() == aString.coder())
            {
                return this.islatin1() ? Stringlatin1.equals(this.value,aString.value) : StringUTF16.equals(this.value,aString.value);
            }
        }
        return false;
    }
}
  1. 那么为什么它被定义为 equals(Object anObject) 而不是 equals(String anObject)? 如果除 String 之外的任何其他对象都返回 false,那么有机会接收任何对象有什么意义?
  2. 如果我创建 MyOwnClass,我应该将 equals() 方法重写为
    equals(Object obj)
    或作为
    equals(MyOwnClass obj)
    如果和第一个选项一样,那么为什么?

P.S.:覆盖时协方差在返回类型中起作用。我认为如果协方差在重写时在返回类型中起作用,那么它也必须在函数参数中起作用。

{
    public A foo(A o)
    {
        return new A();
    }
}

class B extends A
{
    @Override // everything OK
    public B foo(A o)
    {
        return new B();
    }
}

解决方法

到目前为止,没有答案触及问题的核心。

Java 的类型系统是协变的(直到您进入泛型,您可以在其中选择所需的变体)。

给定class Apple extends Fruitclass Fruit extends Object,那么所有的苹果也是水果,所有的水果也是物体,所有的苹果也是物体

而 Object,因为 java.lang.Object 是这样说的,所以有一个 equals(Object other) 方法。这意味着苹果必须也有这个方法:

  1. 所有的苹果都是物体。
  2. 所有对象都有一个 equals(Object) 方法
  3. 因此,苹果有一个 equals(Object) 方法。

那为什么对象有这个方法呢?因为有用。因为它使 ArrayListcontains(Object other) 方法打勾,它使 java.util.Set 工作。一旦你决定所有对象都有一个 equals(Object other) 方法,剩下的(特别是,苹果有一个 equals(Object other) 方法,如果你问它是否等于某个非苹果对象)被锁定;现在是这种情况,仅仅是因为我们在这里设置的系统(这是一个协变类型系统,所有类型继承的基本类型都有一个 equals(Object) 方法)规定它必须如此。

是的,java语言规范实际上保证了这一点;您无法从 Apple 中“删除”equals(Object) 方法。然而,问题的关键在于为什么Java 规范是这样工作的。

,

那么为什么它被定义为 equals(Object anObject) 而不是 as 等于(字符串 anObject)?

class String 覆盖具有以下签名的 Object#equals

public boolean equals(Object obj)

在覆盖的情况下,子类中的方法签名(名称和参数)必须与超类中的相同。如果您更改参数的数量和/或类型,该方法将被重载,而不是被覆盖。

如果我创建 MyOwnClass 我应该将 equals() 方法重写为 equals(Object obj) 或 as equals(MyOwnClass obj)

您应该将其覆盖为

public boolean equals(Object obj)

否则不会被覆盖;相反,它会像上面提到的那样过载。

,

如果对于 String 以外的任何其他对象返回 false,那么有机会接收任何对象有什么意义?

给定两个 Object,您可以合法地询问它们是否相等,即使具体类型是 IntegerString

Object first = 0;   // first is an Integer
Object second = ""; // second is a String

boolean equal = second.equals(first);

equals 方法需要接受最通用的类​​型。

我应该将 equals() 方法覆盖为 equals(Object obj) 还是 equals(MyOwnClass obj) 如果在第一个选项中那么为什么?

第一个。如果您使用第二种方式,则只有当接收者和参数都是 MyOwnClass 类型时才会调用它(如 receiver.equals(parameter))。否则,将调用 equals(Object) 中的 Object,因为方法重载由编译器解决,而 equals(Object) 是编译器知道的唯一匹配接收器和参数的方法。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...