Java Object equals()方法详解:默认行为与重写实践
在Java开发中,区分对象的“相等”(相同内容)与“同一”(同一内存引用)是基础核心概念。Object类的equals()方法默认仅比较内存地址。本文将深入剖析其底层机制、默认行为表现,以及在实际业务场景如何通过重写来实现基于属性的逻辑相等判断,结合String类的实现原理说明自定义重写的必要性。
Object类与equals()的基本定位
java.lang.Object 位于Java核心包中,编译时自动导入,是所有Java类的根父类。无论是常规对象还是数组,都隐含地继承了Object类的方法。因此,每个Java开发者都能对任意类型调用 equals() 方法。
虽然语法上所有对象都能调用它,但其在基类中的定义非常基础:
- 方法签名:
public boolean equals(Object obj) - 核心职责:指示其他某个对象是否与此对象“相等”。
- 注意误区:很多人认为 equals() 天生就是比较内容相等的,实际上在 Object 基类中,它仅负责比较引用同一性(即是否是同一个对象实例)。
默认实现:比较的是“同一”而非“相等”
如果不进行任何特殊处理,直接使用 Object 定义的 equals() 方法,其内部逻辑等同于使用 == 运算符来比较两个引用变量的内存地址。
准备测试环境
为了演示这一现象,我们创建一个简单的 Person 类和一个测试类,不进行任何 equals 的重写操作。
package com.example.demo.test;
public class Person {
private String userName;
private int age; // 原文age为String,这里按常规修正为int以匹配常用逻辑,若需严格对应原文则保留String
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}package com.example.demo.test;
public class Test {
public static void main(String[] args) {
// 创建两个内容相同但地址不同的Person对象
Person p1 = new Person();
p1.setUserName("Alice");
Person p2 = new Person();
p2.setUserName("Alice");
// 1. 使用默认的Object.equals()
System.out.println("p1.equals(p2): " + p1.equals(p2)); // false
// 2. 使用 == 运算符
System.out.println("p1 == p2: " + (p1 == p2)); // false
/*
* 对比:String类重写了Object类的equals()方法
* String类会逐个字符比较内容,即使创建了两个不同的String对象实例
*/
String s1 = new String("Hello");
String s2 = new String("Hello");
System.out.println("s1.equals(s2): " + s1.equals(s2)); // true (比较内容)
System.out.println("s1 == s2: " + (s1 == s2)); // false (比较地址)
}
}
结果分析与String类的启示
从上述代码的执行逻辑可以看出显著差异:
- Object的默认行为:对于
p1和p2,虽然它们的属性看起来一致,但因为它们是new出来的两个独立对象,拥有不同的内存地址,所以equals()返回false。 - String的特殊处理:Java标准库中的
String类觉得这种默认行为不符合人类直觉,因此在源码中 重写 了equals()方法,使其变成“逐字符比较”。
String.equals() 源码核心逻辑参考
了解这一源码有助于理解如何编写业务类的 equals() 方法:
public boolean equals(Object anObject) {
// 第一步:如果引用的是同一个对象,直接返回true(优化性能)
if (this == anObject) {
return true;
}
// 第二步:检查传入的对象是否为String类型
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
// 第三步:长度不同肯定不等
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
// 第四步:逐字符比对
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}总结
在Java中,Object 类提供的 equals() 默认只关注对象是否是“同一个”(Same Identity),而不关心对象内容是否“一样”(Equal Content)。如果你需要比较两个自定义业务对象的数据内容是否相同,必须遵循Java的约定,重写 equals() 方法以及配套的 hashCode() 方法。以上就是Java Object类equals方法的详细内容,更多关于Java equals方法重写的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













