前言
在 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()系列方法则是实现线程同步和通信的重要工具。