您认为将equals
方法放入java.lang.Object
的主要动机是什么?我们覆盖它的大多数实现都是以域为中心的,即在模型类中。我还没有在工厂类或类似的东西中看到equals
的实现。
我的结论是它主要用于支持Java Collection API,因此它可以处理任何Object
。否则,它可能由特定的域设计定义。
==
和equals
之间的区别或写作平等的最佳做法。
答案 0 :(得分:5)
通过将equals
放入Object
,它可以让许多其他类使用equals
方法,而无需具体了解它将处理的对象类型。例如,HashMap
和Hashtable
使用equals
作为其算法的一部分。
将其置于Object
中的另一种方法是使用具有equals
方法的单独接口(或者可能将其与Comparable
结合使用,但具体细节并不重要)。但是,我猜测Java设计者认为在某些情况下使用默认的equals
实现会很有用(这可以确保所有对象都有equals
方法)。
答案 1 :(得分:3)
在Java中包含equals
是一个非常好的语言设计决策。
equals
方法进行私有化是一种不错的方法。==
)是相等测试的合理默认值,但在许多情况下还不够:通常您希望两个对象被认为是相等的,即使它们不是同一个对象(考虑两个具有相同元素的列表,例如)equals
)的顶部定义Object
以便为每个对象实现它,那么它很难/不可能写入处理平等的通用代码。equals
作为核心语言的一部分,您可以预期图书馆生态系统中会出现数百种不同且不兼容的变体。不漂亮!我对equals
设计的主要批评是它假设你有一个有效的非null对象来调用它。通常是正确的,但有时您也需要检查空值。因此,在调用常规equalsWithNulls
之前,我经常最终使用静态equals
方法或类似的方法将空检查考虑在内。
答案 2 :(得分:1)
我几乎是肯定的,其意图是遵循Smalltalk的设计,该设计早于Java,包括(IIRC)#=
和#hash
。 Gosling也喜欢VM的想法,但保留了令人讨厌的C ++语法。也可能是因为Java当时不支持泛型或多重继承(或特征或混合)。
我个人认为.equals()
对可变对象很危险。更重要的是它不是类型安全的(我有许多意外错误比较字符串与其他对象)。我认为Haskell's type classes是equal
的正确方法,但Java确实有足够强大的类型系统来做类似的事情。
答案 3 :(得分:0)
通过同时具有标识和相等性,可以将引用类型与基元区分开来。请考虑以下事项:
int a = 5;
整数a = Integer.valueOf(5);
前者只有值5和整数的自然顺序。另一方面,后者具有-plus-其引用的标识(以及由空引用表示的能力)。
有能力测试这两种品质是有道理的。
现在考虑一下:
这些整数是相同的,但不完全相同。输出是假的(我们假设可以简单地忽略整数的静态工厂'valueOf()'方法。)