ChatGPT解决这个技术问题 Extra ChatGPT

默认 .equals 和 .hashCode 将如何适用于我的课程?

说我有自己的课

public class MyObj { /* ... */ }

它有一些属性和方法。它不实现equals,不实现hashCode。

一旦我们调用 equals 和 hashCode,默认的实现是什么?来自对象类?它们是什么?默认 equals 将如何工作?默认 hashCode 将如何工作以及返回什么? == 只会检查它们是否引用同一个对象,所以这很容易,但是 equals() 和 hashCode() 方法呢?


B
Basil Bourque

是的,默认实现是 Object 的(一般来说;如果您从重新定义 equals 和/或 hashCode 的类继承,那么您将改用该实现)。

从文档中:

equals

Object 类的 equals 方法实现了对象上最有区别的可能等价关系;也就是说,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象(x == y 的值为 true)时,此方法才返回 true。

hashCode

在合理可行的情况下,由 Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但 JavaTM 编程语言不需要这种实现技术。)


请注意,与 hashCode 的文档相反,HotSpot returns a random number per default 作为哈希。另见this blog entry
B
Basil Bourque

来自 JVM 实现之一中的 Object

public boolean equals(Object object) {
    return this == object;
}

public int hashCode() {
    return VMMemoryManager.getIdentityHashCode(this);
}

在这两种情况下,它只是比较相关对象的内存地址。


它来自哪个版本的JDK?在 v6u23 eapublic native int hashCode();
@kha - 你是对的,我想我追踪了一个本地实现,看看它实际上做了什么
“在这两种情况下,它只是比较相关对象的内存地址。”:HotSpot returns a random number per default 作为散列。另见this blog entry
J
Jorn

Object 中有 equals()hashCode() 的默认实现。如果您不提供自己的实现,则将使用这些实现。对于 equals(),这意味着 == 比较:只有当它们是完全相同的对象时,它们才会相等。对于 hashCode()Javadoc 有很好的解释。

有关详细信息,请参阅 Effective Java,Chapter 3 (pdf),第 8 项。


k
khachik

是的,来自 Object 类,因为您的类隐式扩展了 Object。 equals 只返回 this == objhashCode 实现是本机的。只是一个猜测 - 它返回指向对象的指针。


它是指向位于内存中的对象的指针,但它不是对象的内存地址。 GC 可以在内存中移动对象,并且哈希码将保持不变。
@杰里米谢谢。 stackoverflow.com/questions/2427631/… 可能很有趣。
P
Paweł Dyda

如果您不提供自己的实现,则将使用从 Object 派生的实现。没关系,除非您打算将您的类实例放入 HashSet(任何实际使用 hashCode() 的集合),或者需要检查对象相等性的东西(即 HashSet 的 contains() 方法)。否则,如果这是您所要求的,它将无法正常工作。

借助 Apache Commons Lang 中的 HashCodeBuilderEqualsBuilder,您可以很容易地提供这些方法的实现。


(a) 为什么你说 Object 类的默认实现 'equals' 不能与 HashSet 一起正常工作?这与此页面上的其他答案相矛盾。 (b) 感谢 Commons Lang 链接。
@Basil:我认为这并不矛盾。当然默认实现会起作用......不知何故,但不是你期望的方式。也就是说,由于 equals() 使用引用相等,因此在默认实现的眼中,两个相同的对象将是“不同的”。结果,您最终可能会在您的 Set 中拥有完全相同事物的两个不同实例。而 Sets 的典型用法是当您想要消除重复项时......
@PawełDyda:对于可变类型,默认行为通常是正确的。如果 FooBar 是对可变类型的两个不同实例的引用,并且存在一个方法(例如 SomeMutatingMethod)使得 Foo.SomeMutatingMethod() 不会像对 Foo 那样影响 Bar,这种差异应该足以将对象视为不平等。
b
brabster

IBM 的 developerworks 说:

在此默认实现下,两个引用只有在引用完全相同的对象时才相等。类似地,Object 提供的 hashCode() 的默认实现是通过将对象的内存地址映射到一个整数值来派生的。

但是,要确定特定供应商的 Java 版本的确切实现细节,最好查看源代码(如果可用)