介绍一下 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() |
在垃圾回收时调用(已废弃,不推荐使用) | 否 |