Skip to content
第 10 章 后端 ⏱ 8 分钟阅读

第 10 章:Object 类与常用方法 ​

学习目标 ​

  • 理解 Object 是所有类的根
  • 掌握 equals / hashCode / toString 重写
  • 避开 equals 和 hashCode 的常见坑

一、Object 是所有类的祖先 ​

Java 中所有类都直接或间接继承 Object。

java
public class User {
    // 没写 extends,但默认继承 Object
}

User u = new User();
System.out.println(u instanceof Object);  // true

二、equals 默认行为(== 比较地址) ​

java
public boolean equals(Object obj) {
    return (this == obj);    // 默认就是 == 比较
}

业务上需要"值相等"时,必须重写 equals:

java
public class User {
    private String name;
    private int age;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;                          // ① 同一对象,直接返回 true
        if (!(o instanceof User)) return false;              // ② 类型不对,返回 false
        User other = (User) o;
        return age == other.age && Objects.equals(name, other.name);
    }
}

User u1 = new User("张三", 18);
User u2 = new User("张三", 18);
System.out.println(u1.equals(u2));   // true(值相等)

三、equals 和 hashCode 契约 ​

重写 equals 必须同时重写 hashCode,否则用 HashMap / HashSet 会出问题。

java
@Override
public int hashCode() {
    return Objects.hash(name, age);   // 基于字段生成
}

⚠️ 坑 1:两个对象 equals 相等 → hashCode 必须相等。否则:

java
Set<User> set = new HashSet<>();
set.add(new User("张三", 18));
set.contains(new User("张三", 18));   // ❌ false,因为 hashCode 不同找不到

⚠️ 坑 2:字符串比较永远用 equals,不要用 ==:

java
String a = "hi";
String b = new String("hi");
a == b         // ❌ false(地址不同)
a.equals(b)    // ✅ true

四、toString 调试输出 ​

不重写的话,默认打印 类名@哈希码,调试不友好:

java
@Override
public String toString() {
    return "User{name='" + name + "', age=" + age + "}";
}

User u = new User("张三", 18);
System.out.println(u);   // User{name='张三', age=18}

企业建议:每个实体类都重写 toString,调试省事。

五、其他 Object 方法速览 ​

方法用途
getClass()获取运行时类
clone()浅拷贝(基本类型 OK,引用类型共享)
wait() / notify()线程间协作(并发章节)
finalize()GC 前调用(已废弃,别用)

六、实战:完整 User 类 ​

java
import java.util.Objects;

public class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;
        User user = (User) o;
        return age == user.age && Objects.equals(name, user.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "User{name='" + name + "', age=" + age + "}";
    }
}

七、本章小结 ​

要点关键
Object所有类的根,默认继承
equals默认 == 比较,业务需要"值相等"时必须重写
hashCode重写 equals 必须同时重写 hashCode
toString重写后调试更友好
字符串比较永远用 equals,不用 ==

动手练习 ​

  1. 完整实体类:写 Product(id/name/price),重写 equals/hashCode/toString
  2. HashSet 测试:把自定义对象放进 HashSet,验证 equals/hashCode 的作用
  3. IDE 自动生成:用 IDEA 的 Generate → equals() and hashCode(),看生成的代码

下一章:第 11 章:String 与 StringBuilder →

本站基于 VitePress 构建 · 由 StackHub 团队维护