前言
在 Java 中,Object 类是所有类的根类,每个类都直接或间接继承自 Object 类。了解 Object 类的方法对于掌握 Java 编程至关重要。本文将详细介绍 Object 类中常用的方法,并通过代码示例展示它们的用法。
Object 类的主要方法
Object 类包含以下常用方法:
equals(Object obj)
- 比较对象是否相等hashCode()
- 返回对象的哈希码值toString()
- 返回对象的字符串表示getClass()
- 返回对象的运行时类clone()
- 创建并返回对象的副本notify()
- 唤醒在此对象监视器上等待的单个线程notifyAll()
- 唤醒在此对象监视器上等待的所有线程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()
系列方法则是实现线程同步和通信的重要工具。