介绍一下 Object 常见方法?
参考回答**
Object 是 Java 中所有类的父类,它提供了一些通用方法,所有类都可以继承和重写。以下是 Object 类的常见方法及其作用:
public boolean equals(Object obj):- 比较两个对象是否相等,默认实现是比较内存地址,子类通常会重写此方法。
protected Object clone():- 创建并返回对象的副本,需实现
Cloneable接口,否则会抛出CloneNotSupportedException。
- 创建并返回对象的副本,需实现
public String toString():- 返回对象的字符串表示,默认实现返回类名 +
@+ 哈希码(getClass().getName() + "@" + Integer.toHexString(hashCode()))。 - 通常会被重写以提供更有意义的信息。
- 返回对象的字符串表示,默认实现返回类名 +
public int hashCode():- 返回对象的哈希值,默认实现返回内存地址的哈希值,通常与
equals()方法配合重写,用于集合操作(如HashMap、HashSet)。
- 返回对象的哈希值,默认实现返回内存地址的哈希值,通常与
protected void finalize():- 在垃圾回收器回收对象时调用,通常用于清理资源(不推荐直接使用,已在 Java 9 中被标记为废弃)。
public final Class<?> getClass():- 返回对象的运行时类信息。
public final void wait()、public final void wait(long timeout)、public final void wait(long timeout, int nanos):- 让线程等待,直到被唤醒或超时,用于线程同步。
public final void notify()和public final void notifyAll():- 唤醒在该对象上等待的线程,用于线程同步。
详细讲解与扩展
1. equals() 方法
作用:
- 用于比较两个对象是否相等,默认实现是比较两个对象的内存地址。
默认实现:
public boolean equals(Object obj) {
return (this == obj);
}
通常需要重写:
- 在业务场景中,通常需要比较对象的内容(如属性值)而不是内存地址。
重写示例:
public class Person {
private String name;
private int age;
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && Objects.equals(name, person.name);
}
}
2. toString() 方法
作用:
- 返回对象的字符串表示,默认实现是类名 +
@+ 哈希值。
默认实现:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
通常需要重写:
- 使对象更具可读性(如打印对象时显示属性值)。
重写示例:
public class Person {
private String name;
private int age;
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
3. hashCode() 方法
作用:
- 返回对象的哈希值,用于哈希集合(如
HashMap、HashSet)存储时确定桶的位置。
默认实现:
- 基于内存地址计算哈希值。
通常需要重写:
- 如果重写了
equals(),必须同时重写hashCode(),以确保相等的对象具有相同的哈希值。
重写示例:
@Override
public int hashCode() {
return Objects.hash(name, age); // 使用属性计算哈希值
}
注意:
-
hashCode()的约定:
- 如果两个对象根据
equals()方法相等,则它们的hashCode()必须相等。 - 如果两个对象根据
equals()方法不相等,则它们的hashCode()不需要不同(但不同可以提高性能)。
- 如果两个对象根据
4. clone() 方法
作用:
- 创建对象的副本,默认实现是浅拷贝。
默认实现:
- 使用原始对象的二进制数据创建副本。
使用限制:
- 必须实现
Cloneable接口,否则会抛出CloneNotSupportedException。
浅拷贝与深拷贝:
- 浅拷贝:复制对象本身,但内部引用指向同一内存地址。
- 深拷贝:复制对象本身及其所有引用的对象。
浅拷贝示例:
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
深拷贝示例: 需要手动实现深拷贝逻辑(例如序列化/反序列化)。
5. getClass() 方法
作用:
- 获取对象的运行时类信息。
示例:
Person person = new Person();
System.out.println(person.getClass().getName()); // 输出:Person
6. wait() 和 notify() 系列方法
作用:
- 用于线程间的通信,必须在同步块中使用(
synchronized关键字)。
wait() 示例:
synchronized (obj) {
obj.wait(); // 当前线程等待,直到被唤醒
}
notify() 示例:
synchronized (obj) {
obj.notify(); // 唤醒一个正在等待的线程
}
7. finalize() 方法
作用:
- 在垃圾回收器回收对象时调用,用于清理资源。
注意:
- 不推荐使用,可能导致性能问题和不可预测的行为。
- 从 Java 9 开始被标记为废弃。
替代方法: 使用 try-with-resources 或 Closeable 接口来管理资源。
总结
| 方法名 | 作用与特点 | 是否需要重写 |
|---|---|---|
equals(Object obj) |
比较对象是否相等(默认比较内存地址) | 通常需要重写 |
toString() |
返回对象的字符串表示(默认返回类名+哈希值) | 通常需要重写 |
hashCode() |
返回对象的哈希值,用于哈希集合操作 | 通常需要与 equals() 一起重写 |
clone() |
创建对象的副本,默认实现浅拷贝 | 如果需要复制对象时需要重写 |
getClass() |
返回运行时类信息,不需要重写 | 否 |
wait()/notify() |
用于线程通信,必须在同步块中使用 | 否 |
finalize() |
在垃圾回收时调用(已废弃,不推荐使用) | 否 |