深入理解equals(): Jdk源码揭示的五个关键点

0 下载量 29 浏览量 更新于2024-08-31 收藏 344KB PDF 举报
"这篇内容主要讨论了Java中equals()方法的使用和理解,以及与"=="操作符的区别。文中通过一个面试场景引出问题,并分析了JDK源码中的equals()方法实现。文章强调了equals()方法在不同情况下比较的对象内容和地址,特别是在Java多态机制下的表现。同时,提到了在重写equals()方法时,通常是出于在HashMap等数据结构中正确比较自定义对象的需求。" 在Java中,`equals()`方法和"=="操作符有着明显的区别。`==`用于比较两个变量是否指向内存中的同一个对象实例,而`equals()`方法则是用来比较对象的内容或值。然而,这个行为并不是所有类都一致的。在`Object`类中,`equals()`方法默认的行为就是使用"=="来比较两个对象的引用。但许多类,如`String`和一些封装类,已经重写了`equals()`方法,使得它比较的是对象的内容。 当我们在自定义类中使用`equals()`方法时,如果不重写它,那么默认的行为就是和"=="相同,比较对象的引用。但是,如果希望比较的是对象的属性值,我们就需要按照Java社区推荐的规范来重写`equals()`方法,同时还需要重写`hashCode()`方法,以确保对象的平等性与哈希码的一致性。这样做是为了保证在像`HashMap`这样的数据结构中,当对象作为键使用时,能正确地查找和存储。 在`HashMap`中,`containsKey()`方法会调用`getNode()`,后者会根据键的`hashCode()`来定位元素。如果键为`null`,HashMap依然可以处理。如果键不是`null`,则会使用`hashCode()`的结果进行进一步的操作。`equals()`方法在这个过程中起着关键作用,因为当两个键的`hashCode()`相同时,`HashMap`会使用`equals()`来确认它们是否真的是同一个键。 为了确保重写的`equals()`方法符合预期,通常需要遵循以下原则: 1. 自反性:对于任何非空引用x,`x.equals(x)`应返回`true`。 2. 对称性:对于任何非空引用x和y,如果`x.equals(y)`返回`true`,那么`y.equals(x)`也应返回`true`。 3. 传递性:对于任何非空引用x,y和z,如果`x.equals(y)`返回`true`,并且`y.equals(z)`返回`true`,那么`x.equals(z)`也应返回`true`。 4. 一致性:对于任何非空引用x和y,如果x和y的内容始终保持不变,那么多次调用`x.equals(y)`应该始终返回相同的结果。 5. 对于任何非空引用x,`x.equals(null)`应返回`false`。 因此,当我们创建自定义类并打算将其作为Map的键时,务必考虑以上几点,以确保`equals()`和`hashCode()`方法的正确实现。这样,才能保证在使用这些对象时,Map能够正确识别和处理它们。