在 Java 中,java.lang.Object 是所有类的根类(超类)——所有类都直接或间接继承自 Object,包括数组和自定义类。即使定义类时未显式声明父类(如 class A {}),编译器也会默认添加 extends Object

Object 类定义了所有 Java 对象共有的基本行为,提供了 11 个核心方法,这些方法是 Java 面向对象特性(如多态、相等性判断、哈希计算)的基础。

一、Object 类的核心方法解析

1. equals(Object obj):判断两个对象是否“相等”
  • 默认实现return (this == obj);,即比较两个对象的内存地址(仅当是同一个对象时返回 true)。
  • 作用:定义“对象相等”的逻辑,可被重写以实现“逻辑相等”(如通过属性判断,见前文 Person 类示例)。
  • 注意:重写 equals() 时必须同时重写 hashCode(),否则会破坏哈希表(如 HashSet)的正确性。
2. hashCode():返回对象的哈希值
  • 默认实现:返回对象的内存地址转换的整数(不同对象的哈希值大概率不同)。
  • 作用:支持哈希表(HashSetHashMap 等)的高效存储和查找,哈希值用于确定对象在哈希表中的存储位置。
  • 契约规则(必须遵守):
    • a.equals(b) == true,则 a.hashCode() == b.hashCode()
    • a.hashCode() != b.hashCode(),则 a.equals(b) == false
    • a.hashCode() == b.hashCode()a.equals(b) 可能为 truefalse(哈希碰撞)。
3. toString():返回对象的字符串表示
  • 默认实现getClass().getName() + "@" + Integer.toHexString(hashCode()),例如 com.example.Person@1b6d3586(类名 + @ + 哈希值十六进制)。
  • 作用:方便打印对象信息,通常会重写为包含对象属性的字符串,例如:
    @Override
    public String toString() {
        return "Person{name='" + name + "'}";
    }
    
  • 注意:System.out.println(obj) 本质是调用 obj.toString()
4. getClass():返回对象的运行时类
  • 方法签名public final Class<?> getClass()final 修饰,无法重写)。
  • 作用:获取对象的运行时类型(Class 对象),用于反射操作(如获取类名、方法、属性等)。
    Person p = new Person("张三");
    Class<?> cls = p.getClass();
    System.out.println(cls.getName()); // 输出 "com.example.Person"(类的全限定名)
    
5. clone():创建并返回对象的副本
  • 方法签名protected Object clone() throws CloneNotSupportedException
  • 作用:实现对象的“浅拷贝”(复制对象本身,但对象中的引用类型属性仍指向原地址)。
  • 使用条件
    • 类必须实现 Cloneable 接口(标记接口,无实际方法),否则调用 clone() 会抛 CloneNotSupportedException
    • 通常需要重写 clone() 并改为 public 访问权限。
    class Person implements Cloneable {
        private String name;
        @Override
        public Object clone() throws CloneNotSupportedException {
            return super.clone(); // 调用父类(Object)的 clone()
        }
    }
    
6. notify() / notifyAll() / wait():线程同步相关

这三个方法用于多线程间的协作(基于对象的“监视器锁”),均为 final 方法,无法重写:

  • notify():唤醒在此对象监视器上等待的单个线程
  • notifyAll():唤醒在此对象监视器上等待的所有线程
  • wait()(重载方法):使当前线程进入等待状态,直到被 notify()/notifyAll() 唤醒或超时。

示例(生产者-消费者模型中常用):

synchronized (obj) {
    while (条件不满足) {
        obj.wait(); // 线程等待,释放锁
    }
    // 执行操作
    obj.notify(); // 唤醒其他等待线程
}
7. finalize():对象被垃圾回收前的清理操作
  • 方法签名protected void finalize() throws Throwable
  • 作用:在对象被垃圾回收器回收前,由 JVM 调用,用于释放资源(如关闭文件、网络连接等)。
  • 注意
    • 无法保证被调用的时机,也不保证一定会被调用(JVM 可能直接终止而不执行);
    • Java 9 后已标记为 @Deprecated,推荐用 try-with-resources 或手动释放资源替代。

二、Object 类的特殊地位

  1. 所有类的超类
    无论是否显式声明,任何类都继承 Object,因此任何对象都能调用 Object 的方法。例如:

    String s = "hello";
    s.equals("world"); // 调用 Object 定义的 equals()(String 已重写)
    int hash = s.hashCode(); // 调用 Object 定义的 hashCode()(String 已重写)
    
  2. 支持“泛化”处理
    由于所有对象都可向上转型为 ObjectObject 类型变量可接收任意对象,这是早期 Java 实现通用代码的基础(如 ArrayList 最初用 Object[] 存储元素)。

  3. 多态的基础
    Object 类的方法(如 equals()toString())可被重写,子类对象调用这些方法时会执行重写后的逻辑,体现了多态特性。

三、常见面试考点

  1. ==equals() 的区别

    • ==:比较基本类型时是值相等,比较引用类型时是地址相等;
    • equals():默认是地址比较(同 ==),但可重写为逻辑相等(如 Stringequals() 比较字符序列)。
  2. 为什么重写 equals() 必须重写 hashCode()
    若两个对象 equals() 返回 truehashCode() 不同,会导致它们在 HashSet 中被视为不同元素(违背去重逻辑),破坏哈希表的一致性。

  3. clone() 是深拷贝还是浅拷贝?
    默认是浅拷贝:基本类型属性会复制值,引用类型属性仅复制引用(原对象和副本共享该引用指向的对象)。深拷贝需手动实现(递归复制引用对象)。

总结

Object 类是 Java 面向对象体系的基石,它定义的方法为所有对象提供了统一的行为规范,包括相等性判断、哈希计算、字符串表示、线程协作等核心功能。理解 Object 类的方法及其设计意图,是掌握 Java 面向对象编程的基础。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐