7

您认为引入该equals方法的主要动机java.lang.Object是什么?我们覆盖它的大多数实现都是以域为中心的,即在模型类中。我还没有equals在工厂类或等效的东西中看到实现。

我的结论是,它主要用于支持 Java Collection API,因此它可以处理任何Object. 否则,它可能由特定的域设计来定义。

PS:我知道这个线程可能更面向讨论,但没有其他地方可以深入了解这一点。我试图广泛地寻找这个问题的答案,但总是在讨论或解释中讨论或解释写作 equals 之间的区别==equals或最佳实践。

4

4 回答 4

5

通过放入equalsObject它可以让许多其他类使用该equals方法,而无需具体知道它将处理什么类型的对象。例如,HashMapHashtable用作equals其算法的一部分。

将其放入的另一种方法Object是拥有一个具有该equals方法的单独接口(或者可能将其与 结合Comparable,但细节在这里并不重要)。但是,我猜 Java 设计者认为equals在某些情况下使用默认实现会很有用(这可以确保所有对象都有equals方法)。

于 2013-05-28T01:51:53.690 回答
3

equals包含在 Java 中是一个非常好的语言设计决策。

  • 数十年的经验表明,不同类别的对象具有不同的相等语义。您需要一种机制来表达这一点,并且提供多态equals方法是一种不错的方法。
  • 对象标识(==在 Java 领域)是相等测试的合理默认值,但在许多情况下还不够:通常您希望两个对象被视为相等,即使它们不是同一个对象(例如,考虑两个具有相同元素的列表)
  • 如果您没有equals在对象层次结构 ( ) 的顶部定义Object以便为每个对象实现它,那么很难/不可能编写处理相等性的通用代码。
  • 如果您不提供equals作为核心语言的一部分,您可能会期望在图书馆生态系统中出现数百种不同且不兼容的变体。不漂亮!

我对它的设计的主要批评equals是它假设你有一个有效的非空对象来调用它。通常是正确的,但有时您还需要检查空值。结果,我经常最终使用静态equalsWithNulls方法或类似的方法,在调用常规之前考虑空检查equals

于 2013-05-28T03:40:44.787 回答
1

我几乎肯定其意图是遵循 Smalltalk 的设计,该设计早于 Java,包括 (IIRC)#=#hash. Gosling 也喜欢 VM 的想法,但保留了令人讨厌的 C++ 语法。也可能选择它是因为当时的 Java 不支持泛型或多重继承(或特征或混合)。

我个人认为.equals()对可变对象很危险。更重要的是它不是类型安全的(我有很多意外的错误将字符串与其他对象进行比较)。我认为Haskell 的类型类是正确的做法,equal但 Java 确实有一个足够强大的类型系统来做类似的事情。

于 2013-05-28T16:34:52.203 回答
0

引用类型与原语的区别在于具有同一性和相等性。考虑以下:

  • int a = 5;

  • 整数 a = Integer.valueOf(5);

前者只有值 5 和整数的自然排序。另一方面,后者具有它的引用的标识(以及由空引用表示的能力)。

有能力测试这两种品质是有道理的。

现在考虑:

  • System.out.println(new Integer(5) == new Integer(5));

这些整数相等,但不相同。输出为假(假设可以简单地忽略 Integer 的静态工厂 'valueOf()' 方法)。

于 2013-05-29T00:39:57.783 回答