我之前写过关于这里的文章,这里我重新写一篇文章 Java中Object类中的hashCode()和equals()方法如下所示: public boolean equals(Object obj) {
return (this == obj);
}
public int hashCode() {
int lockWord = shadow$_monitor_;
final int lockWordStateMask = 0xC0000000; // Top 2 bits.
final int lockWordStateHash = 0x80000000; // Top 2 bits are value 2 (kStateHash).
final int lockWordHashMask = 0x0FFFFFFF; // Low 28 bits.
if ((lockWord & lockWordStateMask) == lockWordStateHash) {
return lockWord & lockWordHashMask;
}
return System.identityHashCode(this);
}
引用相等性: 堆上同一对象的两个引用 引用到堆上同一个对象的两个引用是相等的。hashCode()默认的行为会返回每个对象特有的序号(大部分的Java版本 是依据内存位置计算此序号,所以不会有相同的hashCode) 如果想要知道两个引用是否相等,可以使用==来比较变量上 的字节组合。如果引用到相同的对象,字节组合也会一样(也就是物理地址一样) 对象相等性: 你必须覆盖hashCode()方法才能确保两个对象有相同的hashcode,也要确保以另一个对象为参数的equals()调用会返回true (这时候你认为只要两个对象实例变量的引用指向同一对象,另外属性中基本数据类型也相同就算是对象相等了)
hashCode()与equals()的相关规定: API文件有对对象的状态制定出必须遵守的规则: (1).如果两个对象相等,则hashcode必须也是相等的 (2).如果两个对象相等,对其中的一个对象调用equals()必须返回true. (3).如果两个对象有相同的hashcode值,它们也不一定时相等的。但若两个对象相等,则hashcode值一定是相等的。 (4).因此若equals()被覆盖过,则hashCode()也必须被覆盖 (5).hashCode()的默认行为是对在heap上的对象产生独特的值。如果你没有override过hashCode(),则该class的两个对象 怎么都不会被认为是相同的。 (6).equals()的默认行为是执行==的比较。也就是说会去测试两个引用是否对上heap同一个对象。如果equals()没有被覆盖过, 两个对象永远不会被视为相同的,因为不同的对象有不同的字节组合 a.equals(b)必须与a.hashCode()==b.hashCode()等值 但a.hashCode() == b.hashCode()不一定要与a.equals(b)等值。 hashcode相同并不一定保证对象是相等的,因为hashCode()所使用的杂凑算法也许刚好会让多个对象传回相同的杂凑值。 |