Java对于重写equals的检查

  Java类的equals方法是从Object类中继承来的,用来判断对象是否逻辑上相等,而不是只判断对象的引用相等(==)。举个例子,判断字符串相等只要两个字符串的内容相等即可,两个字符串的equals就为true,而二者的==并不一定成立。

  Java对重写的equals方法有一定约束,要满足对称性,反射性,类推性,一致性等原则,但实际上对反射性(x.equals(x)必须返回是“true”)并没有检查,看下面的程序:

  这里的equals直接返回的是false,明显不满足反射性,而这段代码编译运行都没有出错;而且在Java官方的API中建议的写法也有一定的问题,在继承中父类和子类对象的比较中并没有满足对称性,由此可见,重写equals方法的约束条件只是建议,而不是强制性的约束,因此我们在重写equals的时候要知道自己在干什么,防止出现上面的情况,虽然逻辑上时错误的,但编译运行都没有问题。

  以前还做过一道很诡异的题:如果2个对象==,则他们一定equals一定是true吗?虽然逻辑上我们一定认为是正确的,但实际上却不一定哦。

O(∩_∩)O~

### 如何在 Java 中正确实现类的 `equals` 方法 为了确保对象之间的比较能够按照预期工作,当创建新的类时,如果该类具有逻辑上的相等概念,则应当重写来自 `Object` 类的 `equals` 方法。以下是具体做法: #### 遵循约定俗成的原则 - **自反性**:对于任何非空引用值 `x`,`x.equals(x)` 应返回 `true`。 - **对称性**:对于任意引用值 `x` 和 `y`,当且仅当 `y.equals(x)` 返回的结果与 `x.equals(y)` 相同。 - **传递性**:对于任意引用值 `x`、`y` 及 `z`,如果 `x.equals(y)` 返回 `true` 并且 `y.equals(z)` 也返回 `true`,那么 `x.equals(z)` 应返回 `true`。 - **一致性**:多次调用 `x.equals(y)` 始终返回相同的结果,前提是对象上用于比较的信息未被修改。 #### 实现细节 考虑一个简单的例子——学生 (`Student`) 类,其中包含姓名属性。如果不重写 `equals` 方法,默认行为会是比较两个实例是否指向同一内存地址;这显然不是期望的行为。通过适当覆盖此方法可以改变这种状况[^2]。 ```java public class Student { private String name; @Override public boolean equals(Object obj) { // 自检情况处理 if (this == obj) return true; // 处理传入参数为空的情况以及不同类型的对象对比 if (obj == null || getClass() != obj.getClass()) return false; // 安全转换类型并执行字段级别的比较 Student other = (Student) obj; return Objects.equals(this.name, other.name); } } ``` 上述代码片段展示了如何安全有效地重写了 `equals` 方法以支持基于内容而非引用的身份验证。这里使用了 `Objects.equals()` 来简化字符串之间潜在的 `null` 检查过程[^3]。 此外,在涉及到复杂的数据结构或多个成员变量的情况下,还需要进一步扩展这个模式来适应更复杂的场景。例如,如果有更多的私有字段参与判断标准的话,就需要逐一加入到条件表达式里去。 最后值得注意的一点是,每当决定要覆写 `equals` 的时候,最好同时也覆写 `hashCode` 方法,因为这两个方法紧密关联在一起,共同影响集合框架内元素存储和检索效率等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值