java.lang.Object.equals()是什么意思?

时间:2013-05-27 14:53:35

标签: java

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

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

PS:我知道这个主题可能更倾向于讨论,但是没有其他方法能够深入了解这一点。我试图在广泛的范围内搜索答案,但总是在讨论或解释==equals之间的区别或写作平等的最佳做法。

4 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

通过同时具有标识和相等性,可以将引用类型与基元区分开来。请考虑以下事项:

  • int a = 5;

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

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

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

现在考虑一下:

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

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