说说Java 中 Object 类的常用的几个方法?详细的讲解一下

前言

在 Java 中,Object 类是所有类的根类,每个类都直接或间接继承自 Object 类。了解 Object 类的方法对于掌握 Java 编程至关重要。本文将详细介绍 Object 类中常用的方法,并通过代码示例展示它们的用法。

Object 类的主要方法

Object 类包含以下常用方法:

  1. equals(Object obj) - 比较对象是否相等
  2. hashCode() - 返回对象的哈希码值
  3. toString() - 返回对象的字符串表示
  4. getClass() - 返回对象的运行时类
  5. clone() - 创建并返回对象的副本
  6. notify() - 唤醒在此对象监视器上等待的单个线程
  7. notifyAll() - 唤醒在此对象监视器上等待的所有线程
  8. wait() - 导致当前线程等待,直到其他线程调用 notify () 或 notifyAll ()

代码示例详细了解这些方法:

import 复制代码
public class ObjectMethodsDemo {
    public static void main(String[] args) {
        // 创建两个Person对象用于演示
        Person person1 = new Person("Alice", 30);
        Person person2 = new Person("Alice", 30);
        Person person3 = person1;
        
        // 1. equals()方法示例
        System.out.println("1. equals()方法演示:");
        System.out.println("person1 equals person2: " + person1.equals(person2));
        System.out.println("person1 equals person3: " + person1.equals(person3));
        System.out.println("person1 equals null: " + person1.equals(null));
        System.out.println("person1 equals String: " + person1.equals("Alice"));
        
        // 2. hashCode()方法示例
        System.out.println("\n2. hashCode()方法演示:");
        System.out.println("person1 hashCode: " + person1.hashCode());
        System.out.println("person2 hashCode: " + person2.hashCode());
        System.out.println("person3 hashCode: " + person3.hashCode());
        
        // 3. toString()方法示例
        System.out.println("\n3. toString()方法演示:");
        System.out.println("person1 toString: " + person1.toString());
        System.out.println("person2 toString: " + person2); // 打印对象默认调用toString()
        
        // 4. getClass()方法示例
        System.out.println("\n4. getClass()方法演示:");
        System.out.println("person1的类名: " + person1.getClass().getName());
        System.out.println("person1是否为Person类实例: " + (person1.getClass() == Person.class));
        
        // 5. clone()方法示例
        System.out.println("\n5. clone()方法演示:");
        try {
            Person personClone = (Person) person1.clone();
            System.out.println("克隆对象: " + personClone);
            System.out.println("原对象与克隆对象是否相同: " + (person1 == personClone));
            System.out.println("原对象与克隆对象内容是否相等: " + person1.equals(personClone));
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        
        // 6-8. wait(), notify()和notifyAll()方法示例
        System.out.println("\n6-8. wait()和notify()方法演示:");
        MessageBox messageBox = new MessageBox();
        
        // 创建并启动消费者线程
        Thread consumer = new Thread(() -> {
            messageBox.takeMessage();
        }, "消费者线程");
        
        // 创建并启动生产者线程
        Thread producer = new Thread(() -> {
            messageBox.putMessage("Hello, World!");
        }, "生产者线程");
        
        consumer.start();
        try {
            Thread.sleep(1000); // 确保消费者先启动
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        producer.start();
        
        try {
            consumer.join();
            producer.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    // 自定义类演示Object方法重写
    static class Person implements Cloneable {
        private String name;
        private int age;
        
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        
        // 重写equals方法
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Person person = (Person) o;
            return age == person.age && Objects.equals(name, person.name);
        }
        
        // 重写hashCode方法
        @Override
        public int hashCode() {
            return Objects.hash(name, age);
        }
        
        // 重写toString方法
        @Override
        public String toString() {
            return "Person{name='" + name + "', age=" + age + "}";
        }
        
        // 重写clone方法
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    
    // 演示wait()和notify()的类
    static class MessageBox {
        private String message;
        private boolean hasMessage = false;
        
        // 放入消息
        public synchronized void putMessage(String msg) {
            while (hasMessage) {
                try {
                    wait(); // 如果已有消息,等待
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    return;
                }
            }
            this.message = msg;
            hasMessage = true;
            System.out.println(Thread.currentThread().getName() + " 放入消息: " + msg);
            notify(); // 通知等待的线程
        }
        
        // 取出消息
        public synchronized String takeMessage() {
            while (!hasMessage) {
                try {
                    System.out.println(Thread.currentThread().getName() + " 等待消息...");
                    wait(); // 如果没有消息,等待
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    return null;
                }
            }
            hasMessage = false;
            String msg = this.message;
            System.out.println(Thread.currentThread().getName() + " 取出消息: " + msg);
            notify(); // 通知等待的线程
            return msg;
        }
    }
}

具体方法:

1. equals(Object obj)

equals()方法用于比较两个对象是否相等。默认实现是比较对象的引用(即==),但通常需要在自定义类中重写此方法以实现内容比较。

重写equals()时应遵循以下约定:

  • 自反性:x.equals(x)应返回 true
  • 对称性:x.equals(y)y.equals(x)结果一致
  • 传递性:若x.equals(y)y.equals(z)都为 true,则x.equals(z)也应为 true
  • 一致性:多次调用结果应一致
  • 非空性:x.equals(null)应返回 false

2. hashCode()

hashCode()返回对象的哈希码值,主要用于哈希表(如 HashMap)中。重写equals()时必须同时重写hashCode(),以保证相等的对象具有相同的哈希码。

3. toString()

toString()返回对象的字符串表示。默认实现是类名加 "@" 加哈希码的十六进制。重写此方法可以返回更有意义的对象描述。

4. getClass()

getClass()返回对象的运行时类对象,可用于反射操作。该方法是 final 的,不能被重写。

5. clone()

clone()用于创建并返回对象的副本。要使用此方法,类必须实现Cloneable接口,否则会抛出CloneNotSupportedException。默认是浅拷贝。

6-8. wait (), notify () 和 notifyAll ()

这些方法用于线程间通信,必须在同步代码块或同步方法中调用:

  • wait():使当前线程等待,释放对象锁
  • notify():唤醒在此对象上等待的一个线程
  • notifyAll():唤醒在此对象上等待的所有线程

总结

Object 类的这些方法构成了 Java 对象模型的基础,理解并正确使用它们对于编写高质量的 Java 代码至关重要。特别是equals()hashCode()toString()方法,在自定义类中通常需要重写以提供更合理的行为。而wait()notify()系列方法则是实现线程同步和通信的重要工具。

相关推荐
回家路上绕了弯2 小时前
主从架构选型指南:从原理到落地,搞懂怎么选才适合你的业务
后端·架构
沐怡旸2 小时前
【算法】【链表】328.奇偶链表--通俗讲解
算法·面试
沐怡旸2 小时前
【底层机制】std::weak_ptr解决的痛点?是什么?如何实现?如何正确用?
c++·面试
该用户已不存在2 小时前
Rust Web框架大比拼:Actix vs Axum vs Rocket,别再只看跑分了
后端·rust
OneWind2 小时前
使用CloudFlare R2上传图片慢怎么解决
后端
River4162 小时前
Javer 学 c++(十六):对象特性篇(上)
c++·后端
甜瓜看代码2 小时前
业务稳定性和性能稳定性做的工作
面试
文心快码BaiduComate2 小时前
轻松实践:用Python实现“名字大作战”游戏,表白Zulu!
前端·后端·微信小程序
bobz9652 小时前
tc 的锁问题
后端