栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

覆盖Object.equals VS重载它

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

覆盖Object.equals VS重载它

这是因为重载该方法不会更改在集合或其他

equals(Object)
明确使用该方法的位置中的行为。例如,使用以下代码:

public class MyClass {    public boolean equals(MyClass m) {        return true;    }}

如果您将其放在类似

HashSet

public static void main(String[] args) {    Set<MyClass> myClasses = new HashSet<>();    myClasses.add(new MyClass());    myClasses.add(new MyClass());    System.out.println(myClasses.size());}

即使您希望所有实例在过载时都相等,并且不会设置第二个实例

2
,这将打印出,而不是。
1``MyClass

所以基本上,即使这是

true

MyClass myClass = new MyClass();new MyClass().equals(myClass);

这是

false

Object o = new MyClass();new MyClass().equals(o);

后者是集合和其他类用于确定相等性的版本。实际上,此参数将返回的 唯一 地方

true
是该参数显式
MyClass
为其子类型的实例或其子类型之一。


编辑: 根据您的问题:

覆盖与重载

让我们从覆盖和重载之间的区别开始。通过覆盖,您实际上可以 重新定义 该方法。您删除它的原始实现,然后用您自己的替换。因此,当您这样做时:

@Overridepublic boolean equals(Object o) { ... }

您实际上是在重新链接新的

equals
实现,以替换中的实现
Object
(或最后定义它的任何超类)。

另一方面,当您这样做时:

public boolean equals(MyClass m) { ... }

您正在定义一个全新的方法,因为您正在定义一个名称相同但参数不同的方法。当

HashSet
来电
equals
时,它调用它的类型的变量
Object

Object k;if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {

(该代码来自的源代码

HashMap.put
,用作的基础实现
HashSet.add
。)

需要明确的是,它会使用不同的唯一时间

equals
是当一个
equals
方法被 覆盖
,不会过载。如果尝试添加
@Override
到重载的
equals
方法中,它将因编译器错误而失败,并抱怨它没有覆盖方法。我什至可以
equals
在同一个类中声明两个方法,因为它很重载:

public class MyClass {    @Override    public boolean equals(Object o) {        return false;    }    public boolean equals(MyClass m) {        return true;    }}

泛型

至于仿制药,

equals
通用的。它明确地采用
Object
其类型,因此这一点没有意义。现在,假设您尝试执行此操作:

public class MyGenericClass<T> {    public boolean equals(T t) {        return false;    }}

这不会与以下消息一起编译:

名称冲突:MyGenericClass类型的equals(T)方法具有与Object类型的equals(Object)相同的擦除,但不会覆盖它

如果您尝试这样

@Override
做:

public class MyGenericClass<T> {    @Override    public boolean equals(T t) {        return false;    }}

您将得到以下信息:

类型MyGenericClass的equals(T)方法必须重写或实现一个超类型方法

所以你赢不了。这里发生的是Java使用擦除实现泛型。Java在编译时完成对所有通用类型的检查后,实际的运行时对象都将替换为

Object
。在您看到的所有地方
T
,实际的字节码都包含
Object
在内。这就是为什么反射不适用于泛型类以及为什么您不能做类似的事情的原因
listinstanceof List<String>

这也使其无法泛型类型重载。如果您有此类:

public class Example<T> {    public void add(Object o) { ... }    public void add(T t) { ... }}

您会从

add(T)
方法中得到编译器错误,因为当类实际完成编译时,这两个方法将具有相同的签名
public void add(Object)



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/485722.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号