☰
【Java 基础深度解析】Object 类(下)hashCode、clone、wait/notify 源码与面试题汇总
2026/9/28 20:13:36 网站建设 项目流程

前言

上一篇文章,我们学习了 Object 基础继承关系、toString、equals 方法。本篇继续讲解 Object 剩下的核心方法:hashCode、clone、getClass、wait、notify、finalize,附带完整实体案例、全部面试高频题。

一、hashCode () 方法,equals 好搭档

黄金规则:只要重写 equals,就必须重写 hashCode!契约规定: 如果两个对象equals()相等,那么它们hashCode()返回值一定相等。 hashCode 相等,对象不一定 equals 相等(哈希碰撞)。

如果只重写 equals,不改 hashCode,放入HashSet、HashMap会出现诡异 BUG。集合底层先比对 hashCode,hash 不同直接判定对象不同。

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

同样 IDEA 可以一键生成 equals+hashCode 成对代码。

二、getClass () 方法(final,不能重写)

返回对象运行时Class对象,反射技术的入口。

Student s = new Student("张三",18); Class<?> clazz = s.getClass(); System.out.println(clazz.getName()); //输出全类名

区分:getClass()获取运行时真实类型;instanceof做类型判断。

三、clone () 对象克隆

clone()是 protected 方法,默认浅拷贝。想要调用克隆,类需要实现标记接口Cloneable。

  • 浅拷贝:对象本身复制,对象里面引用类型成员,只复制引用地址,新旧对象共用同一个子对象。
  • 深拷贝:逐层复制所有引用对象。
class Student implements Cloneable{ @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }

开发中一般很少直接用 clone 方法,更多使用 Bean 拷贝工具类。

四、wait () notify () notifyAll ()

三个方法被 final 修饰,不能重写,作用于多线程,对象锁监视器。 只有在synchronized同步代码块内部才可以调用。

  • wait():释放锁,当前线程阻塞等待
  • notify():随机唤醒一个等待该对象锁的线程
  • notifyAll():唤醒全部等待线程

这三个方法为什么放在 Object 而不是 Thread?因为锁属于对象,不是线程。每一个 Java 对象都有监视器锁,所以 wait/notify 归 Object 管理。

五、finalize ()(了解即可)

JDK9 之后标记废弃。 垃圾回收器准备回收对象前调用该方法,不要依赖它做资源释放,执行时机不确定,不推荐使用。

六、综合完整实体示例

import java.util.Objects; public class Student { private String name; private Integer age; public Student(String name, Integer age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return Objects.equals(name, student.name) && Objects.equals(age, student.age); } @Override public int hashCode() { return Objects.hash(name, age); } public static void main(String[] args) { Student s1 = new Student("张三",18); Student s2 = new Student("张三",18); System.out.println(s1); System.out.println(s1.equals(s2)); System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); } }

七、面试真题问答(文末加餐)

Q1:Object 类有哪些方法? A:toString、equals、hashCode、clone、finalize、getClass、wait、notify、notifyAll。

Q2:为什么重写 equals 一定要重写 hashCode? A:遵守 hashCode 契约,保证哈希集合 HashMap、HashSet 正常工作。相等对象哈希码必须相同。

Q3:wait 为什么写在 Object 里面而不是 Thread? A:Java 锁是绑定对象监视器 monitor,任意对象都可以作为锁,因此等待唤醒方法归属 Object。

结语

Object 看着简单,却是 Java 面向对象根基。很多进阶内容集合、反射、并发都绕不开它。 写业务实体类养成好习惯,自动生成 toString、equals、hashCode,避开 90% 新手坑。 本篇文章如果对你有帮助,欢迎点赞收藏。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询