默认.equals和.hashCode将如何为我的课程工作?


106

说我有自己的课程

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

它具有一些属性和方法。它不实现等于,不实现hashCode。

一旦我们调用equals和hashCode,默认的实现是什么?从对象类?那是什么 默认值等于如何工作?默认的hashCode将如何工作,返回什么?==只会检查它们是否引用同一个对象,因此很容易,但是equals()和hashCode()方法呢?

Answers:


94

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

从文档中:

equals

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

hashCode

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


50

Object其中一种JVM实现中:

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

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

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


7
它来自什么版本的JDK?在v6u23 eapublic native int hashCode();
khachik

@kha-没错,我想我追踪了其中一个本机实现,以了解它的实际作用
Brad Mace

10

还有的默认实现equals(),并hashCode()在对象。如果您不提供自己的实现,则将使用这些实现。对于equals(),这意味着进行==比较:如果对象是完全相同的对象,则它们将相等。对于hashCode()Javadoc有一个很好的解释。

有关更多信息,请参见有效Java,第3章(pdf),项目8。


1

是的,从Object类开始,因为您的类隐式扩展了Object。equals简单地返回this == objhashCode实现是本地的。只是一个猜测-它返回指向对象的指针。


2
它是指向内存中对象的指针,但不是对象的内存地址。GC可以在内存中移动对象,并且哈希码将保持不变。
杰里米

@杰里米谢谢。stackoverflow.com/questions/2427631/…可能很有趣。
卡其奇

1

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

这是很容易给自己的机制,这些得益于方法的HashCodeBuilderEqualsBuilder阿帕奇共享郎


(a)为什么您说Object类的'equals'默认实现不能与HashSet一起正常使用?这与本页上的其他答案相矛盾。(b)感谢下议院郎链接。
罗勒·布尔克

1
@罗勒:我认为这并不矛盾。当然,默认实现会以某种方式起作用……但不是您期望的那样。也就是说,由于equals()使用引用相等,因此在默认实现的眼中,两个其他相同的对象将是“不同的”。结果,您可能最终在Set中拥有两个完全相同的事物的不同实例。而比较典型的使用设置的是当你想消除重复...
帕维尔Dyda

@PawełDyda:对于可变类型,默认行为通常是正确的。如果FooBar是对可变类型的两个不同实例的引用,并且存在一种方法(例如SomeMutatingMethodFoo.SomeMutatingMethod()不会影响Bar它的相同方式,则Foo该差异应足以将对象视为不相等。
supercat 2012年

0

IBM的developerWorks说:

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

但是,为了确保特定供应商的Java版本的确切实现细节,最好将其视为源(如果有)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.