Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Java';s面积#等于方法不覆盖对象#等于?_Java_Equals - Fatal编程技术网

为什么Java';s面积#等于方法不覆盖对象#等于?

为什么Java';s面积#等于方法不覆盖对象#等于?,java,equals,Java,Equals,我刚刚遇到了一个由Java的Java.awt.geom.Area#equals(Area)方法引起的问题。问题可简化为以下单元测试: @org.junit.Test public void testEquals() { java.awt.geom.Area a = new java.awt.geom.Area(); java.awt.geom.Area b = new java.awt.geom.Area(); assertTrue(a.equals(b)); // -&

我刚刚遇到了一个由Java的
Java.awt.geom.Area#equals(Area)
方法引起的问题。问题可简化为以下单元测试:

@org.junit.Test
public void testEquals() {
    java.awt.geom.Area a = new java.awt.geom.Area();
    java.awt.geom.Area b = new java.awt.geom.Area();
    assertTrue(a.equals(b)); // -> true

    java.lang.Object o = b;
    assertTrue(a.equals(o)); // -> false
}
经过一番努力和调试,我终于在JDK源代码中看到,
区域中的
等于
方法的签名如下所示:

public boolean equals(Area other)
请注意,它不会从
对象
覆盖正常的
等于
方法,而只是使用更具体的类型重载该方法。因此,上面示例中的两个调用最终调用了
equals
的不同实现

由于这种行为自Java1.2以来就一直存在,所以我假设它不被认为是一个bug。因此,我更感兴趣的是找出为什么决定不正确地重写
equals
方法,但同时提供一个重载变量。(这是一个实际决定的另一个提示是缺少覆盖的
hashCode()
方法。)

我唯一的猜测是,作者担心在将
区域
放置在
集合
映射
等数据结构中时,区域的缓慢
等于
实现不适合比较相等性。(在上面的示例中,您可以将
a
添加到
HashSet
,虽然
b
等于
a
,调用
包含(b)
将失败。)那么,他们为什么不以一种与
等于
方法这样一个基本概念不冲突的方式命名有问题的方法呢?

“为什么Java的Area#equals方法不重写Object#equals?”

因为重载方法不需要重写,因为重载方法的参数类型不同

重写的方法与父类中的方法具有完全相同的方法名称、返回类型、参数数量和参数类型,唯一的区别是方法的定义

本案并不强迫我们撤销,但它是超载的,因为它遵循以下规则:

1.)不同方法的参数数量不同

2.)参数类型不同(如将浮点参数更改为int)

“为什么他们不以一种与equals方法这样一个基本概念不冲突的方式命名这个有问题的方法?”

因为这可能会让人们走向未来。如果我们有一台90年代的时间机器,我们可以不用担心这个问题。

上面的评论链接到Real怀疑论者。该错误中的错误解释了原因:

重写equals(Object)的问题是,您还必须 重写hashCode()以返回一个值,该值保证等于() 仅当两个对象的哈希代码也相等时,才为true

但是:

这里的问题是面积。等于(面积)不能执行非常简单的运算 直截了当的比较。它仔细地检查每一个 两个区域中的几何图形,并测试它们是否覆盖 相同的封闭空间。两个面积对象可以具有完全相同的 同一封闭空间的不同描述和相等(面积) 会发现它们是一样的

因此,基本上,我们只剩下一系列不太令人愉快的选择,例如:

弃用equals(Area)并为其创建一个备用名称 操作,如“areasEqual”,以避免混淆。 不幸的是,旧方法将保留下来,并且可以链接和使用 将诱捕许多打算调用equals(对象)的人 版本

或:

弃用equals(Area)并将其实现更改为 equals(Object)的用法,以避免错误时出现语义问题 方法。请使用其他名称创建新方法以避免 无法实现equals(Area)提供的旧功能

或:

实现equals(对象)以调用equals(区域)并实现虚拟 hashCode(),它在退化的 这将使hashCode方法 基本上是无用的,并使区域对象几乎无用的关键帧 哈希映射或哈希表

或者通过其他方式修改
equals(Area)
行为,从而改变其语义或使其与
hashCode
不一致


看起来,维护人员认为更改此方法既不可行(因为bug注释中列出的选项都不能完全解决问题),也不重要(因为该方法在实现时非常慢,并且可能只有在将
区域的实例与自身进行比较时才会返回true,正如评论员所建议的)。

注意
hashCode
也没有被覆盖。我认为他们在这里所做的只是提供一个“比较”“恰好与
Object.equals()同名的方法”
。就我个人而言,我会给它起一个不同的名字以避免混淆。Java API并不总是遵循最佳实践,这看起来像是一个疏忽。试着在Oracle开发人员电子邮件列表中提出这个问题,看看官方用词是什么。如果是疏忽,Sun/Oracle一直都不愿意让API改变nges发布后。这可能意味着它一开始是一个疏忽,导致它成为一个发布,现在只是冻结在时间上。看你误解了他的问题。问题是为什么你会重载它,而不是重写它。由@realponsult链接的错误提供了一些见解。@DeepakBala我指定了为什么你不重写它,以及如何重写它这个概念遵循重载规则。不确定你的意思,因为我似乎回答了这个问题,你能澄清一下吗?对不起,但正如我在问题中所说的,我非常清楚什么是重载和重载,以及何时可以使用它们。但是@