Java面试题-两个对象相等equals相等吗,equals相等对象相等吗
这是一个非常经典的Java面试题,它核心考察的是你对对象相等性判断的深入理解。简单来说,这
两个说法并不总是成立,关键在于如何定义“相等”。
下面这个表格清晰地展示了它们的关系:
情形 | 两个对象相等 (内存地址相同) |
| 说明 |
---|---|---|---|
默认情况 (未重写 | ✅ 意味着 | ❌ 不意味着 对象相等 | 此时 |
重写 | ❌ 不意味着 | ✅ 意味着 被逻辑上认为是相等的 | 此时 |
⚖️ 深入解析相等性
1. “两个对象相等” 是否意味着 equals
为 true
?
这里的“对象相等”通常指两个引用指向同一个内存对象(即使用 ==
比较为 true
)。
-
结论:是的,必然为
true
。 -
原因:根据
equals
方法的约定,其实现必须满足自反性(x.equals(x)
为true
)。如果一个引用和它自己比较都不相等,那就违反了最基本的原则。即使在重写的equals
方法中,第一行检查也通常是if (this == obj) return true;
,用于优化性能。
2. equals
为 true
是否意味着“两个对象相等”?
这里的“对象相等”指两个引用指向同一个内存对象。
-
结论:不一定。
-
原因:当我们重写
equals
方法后,它比较的不再是内存地址,而是对象的逻辑内容。例如,两个不同的String
对象new String("abc")
,它们位于内存的不同位置(==
比较为false
),但因为字符序列完全相同,equals
比较会返回true
。在这种情况下,我们说它们在逻辑上是相等的,但不是同一个对象。
🔗 equals
与 hashCode
的黄金法则
这是一个至关重要的关联规则:当你重写了 equals
方法,你必须同时重写 hashCode
方法。
-
规则:如果两个对象根据
equals
方法是相等的,那么调用它们的hashCode
方法必须产生相同的整数结果。 -
为何重要:这条规则主要是为了保障基于哈希表的集合类(如
HashMap
,HashSet
,Hashtable
)能正常工作。这些集合依赖hashCode
来快速定位对象。 -
违反后果:如果两个对象
equals
相等但hashCode
不相等,它们可能会被插入到哈希表的不同位置,导致你无法正常地从集合中检索到该对象,甚至可能使集合中存在重复元素(违反Set
的唯一性)。
💡 面试进阶要点
-
equals
的五大原则:-
自反性:
x.equals(x)
必须返回true
。 -
对称性:如果
x.equals(y)
为true
,那么y.equals(x)
也必须为true
。 -
传递性:如果
x.equals(y)
为true
,且y.equals(z)
为true
,那么x.equals(z)
也必须为true
。 -
一致性:只要对象没有被修改,多次调用
x.equals(y)
应该始终返回相同的结果。 -
非空性:对任何非
null
的x
,x.equals(null)
必须返回false
。
-
-
==
与equals
的根本区别:-
==
:对于基本类型,比较的是值;对于引用类型,比较的是内存地址。 -
equals
:默认行为与==
相同,但可以被重写用于比较对象的逻辑内容。
-
-
重写
equals
和hashCode
的最佳实践:-
使用 IDE 或
java.util.Objects
类的equals
和hash
方法来安全、简洁地实现。 -
确保在
hashCode
计算中使用所有在equals
比较中使用的“关键域”。
-