为什么 String class 中的 equals 方法定义为 equals(Object anObject) 而不是 equals(String anObject)?
Why equals method in the String class defined as equals(Object anObject) but not as equals(String anObject)?
这是 equals()
来自 String
class
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;
}
}
- 那么为什么它被定义为
equals(Object anObject)
而不是equals(String anObject)
呢?
如果对于 String
之外的任何其他对象 return 为 false,那么有机会接收任何对象有什么意义?
- 如果我创建
MyOwnClass
,我是否应该将 equals()
方法重写为
equals(Object obj)
或者作为
equals(MyOwnClass obj)
如果像第一个选项那么为什么?
P.S.: 重写时协方差在 return 类型中起作用。我认为如果重写时协方差在 return 类型中起作用,那么它也必须在函数参数中起作用。
{
public A foo(A o)
{
return new A();
}
}
class B extends A
{
@Override // everything OK
public B foo(A o)
{
return new B();
}
}
So why it is defined as equals(Object anObject) but not as
equals(String anObject)?
class String
覆盖具有以下签名的 Object#equals
:
public boolean equals(Object obj)
在覆盖的情况下,子class中的方法签名(名称和参数)必须与父class中的相同。如果更改参数的数字 and/or 类型,该方法将被重载,而不是被覆盖。
If I create MyOwnClass should I override equals() method as
equals(Object obj) or as equals(MyOwnClass obj)
您应该将其覆盖为
public boolean equals(Object obj)
否则不会被覆盖;相反,它会像上面提到的那样超载。
What's the point of having an opportunity to receive any object if it's return false for any other objects than String?
给定两个 Object
,您可以合理地询问它们是否相等,即使具体类型是 Integer
和 String
。
Object first = 0; // first is an Integer
Object second = ""; // second is a String
boolean equal = second.equals(first);
equals
方法需要接受最一般的类型。
should I override equals() method as equals(Object obj)
or as equals(MyOwnClass obj)
If as in the first option then why?
第一个。如果你使用第二种方式,只有当接收者和参数都是MyOwnClass
类型时才会调用它(如receiver.equals(parameter)
)。否则,将调用 Object
中的 equals(Object)
,因为方法重载由编译器解决,而 equals(Object)
是编译器唯一知道的匹配接收者和参数的方法。
目前还没有答案触及问题的核心。
Java 的打字系统是协变的(直到你进入泛型,你可以在其中选择你想要的变体)。
鉴于class Apple extends Fruit
和class Fruit extends Object
,那么所有的苹果也是水果,所有的水果也是对象,所有的苹果也是对象。
而 Object,因为 java.lang.Object
这么说,所以有一个 equals(Object other)
方法。也就是说苹果一定也有这个方法:
- 所有的苹果都是对象。
- 所有对象都有一个
equals(Object)
方法
- 因此,苹果有一个
equals(Object)
方法。
那么为什么对象会有这个方法呢?因为它很有用。因为它使 ArrayList
的 contains(Object other)
方法生效,所以它使 java.util.Set 工作。一旦你决定所有对象都有一个 equals(Object other)
方法,其余的(具体来说,苹果有一个 equals(Object other)
方法,如果你问它是否等于 returns false一些非苹果对象)被锁定;现在就是这种情况,因为我们在这里设置的系统(这是一个协变类型系统,其中所有类型继承的基类型都有一个 equals(Object)
方法)规定它必须如此。
是的,java 语言规范实际上保证了这一点;您不能 'remove' 来自 Apples 的 equals(Object)
方法。然而,问题的症结在于 为什么 java 规范是这样工作的。
这是 equals()
来自 String
class
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;
}
}
- 那么为什么它被定义为
equals(Object anObject)
而不是equals(String anObject)
呢? 如果对于String
之外的任何其他对象 return 为 false,那么有机会接收任何对象有什么意义? - 如果我创建
MyOwnClass
,我是否应该将equals()
方法重写为
equals(Object obj)
或者作为
equals(MyOwnClass obj)
如果像第一个选项那么为什么?
P.S.: 重写时协方差在 return 类型中起作用。我认为如果重写时协方差在 return 类型中起作用,那么它也必须在函数参数中起作用。
{
public A foo(A o)
{
return new A();
}
}
class B extends A
{
@Override // everything OK
public B foo(A o)
{
return new B();
}
}
So why it is defined as equals(Object anObject) but not as equals(String anObject)?
class String
覆盖具有以下签名的 Object#equals
:
public boolean equals(Object obj)
在覆盖的情况下,子class中的方法签名(名称和参数)必须与父class中的相同。如果更改参数的数字 and/or 类型,该方法将被重载,而不是被覆盖。
If I create MyOwnClass should I override equals() method as equals(Object obj) or as equals(MyOwnClass obj)
您应该将其覆盖为
public boolean equals(Object obj)
否则不会被覆盖;相反,它会像上面提到的那样超载。
What's the point of having an opportunity to receive any object if it's return false for any other objects than String?
给定两个 Object
,您可以合理地询问它们是否相等,即使具体类型是 Integer
和 String
。
Object first = 0; // first is an Integer
Object second = ""; // second is a String
boolean equal = second.equals(first);
equals
方法需要接受最一般的类型。
should I override equals() method as
equals(Object obj)
or asequals(MyOwnClass obj)
If as in the first option then why?
第一个。如果你使用第二种方式,只有当接收者和参数都是MyOwnClass
类型时才会调用它(如receiver.equals(parameter)
)。否则,将调用 Object
中的 equals(Object)
,因为方法重载由编译器解决,而 equals(Object)
是编译器唯一知道的匹配接收者和参数的方法。
目前还没有答案触及问题的核心。
Java 的打字系统是协变的(直到你进入泛型,你可以在其中选择你想要的变体)。
鉴于class Apple extends Fruit
和class Fruit extends Object
,那么所有的苹果也是水果,所有的水果也是对象,所有的苹果也是对象。
而 Object,因为 java.lang.Object
这么说,所以有一个 equals(Object other)
方法。也就是说苹果一定也有这个方法:
- 所有的苹果都是对象。
- 所有对象都有一个
equals(Object)
方法 - 因此,苹果有一个
equals(Object)
方法。
那么为什么对象会有这个方法呢?因为它很有用。因为它使 ArrayList
的 contains(Object other)
方法生效,所以它使 java.util.Set 工作。一旦你决定所有对象都有一个 equals(Object other)
方法,其余的(具体来说,苹果有一个 equals(Object other)
方法,如果你问它是否等于 returns false一些非苹果对象)被锁定;现在就是这种情况,因为我们在这里设置的系统(这是一个协变类型系统,其中所有类型继承的基类型都有一个 equals(Object)
方法)规定它必须如此。
是的,java 语言规范实际上保证了这一点;您不能 'remove' 来自 Apples 的 equals(Object)
方法。然而,问题的症结在于 为什么 java 规范是这样工作的。