在Java开发中,90%的对象操作都离不开Object类的方法,但大多数开发者仅停留在表面理解。本文将深入源码揭示每个方法的底层机制,并通过真实场景展示如何正确使用这些基础但强大的工具。
toString()
:对象的身份证// OpenJDK 17 源码
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
最佳实践:
// 重写示例(IDEA自动生成)
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
// 使用场景
// 1. 日志打印
log.debug("Current user: {}", user);
// 2. 调试时快速查看对象状态
System.out.println(user);
equals()
& hashCode()
:对象判等的黄金组合// equals() 默认实现
public boolean equals(Object obj) {
return (this == obj);
}
重写规范:
@Override
public boolean equals(Object o) {
// 1. 地址相同
if (this == o) return true;
// 2. 类型检查
if (o == null || getClass() != o.getClass()) return false;
// 3. 字段比较
User user = (User) o;
return id == user.id &&
Objects.equals(name, user.name) &&
Objects.equals(email, user.email);
}
@Override
public int hashCode() {
// 使用JDK工具类避免NPE
return Objects.hash(id, name, email);
}
HashMap中的应用:
Map<User, String> userProfile = new HashMap<>();
// 未重写hashCode/equals时:
User u1 = new User(1, "Alice");
User u2 = new User(1, "Alice");
userProfile.put(u1, "VIP");
userProfile.get(u2); // 返回null!
// 正确重写后返回"VIP"
wait()
/notify()
:线程协作的基石// 生产者-消费者模型实现
public class MessageQueue {
private Queue<String> queue = new LinkedList<>();
private int maxSize = 10;
public synchronized void produce(String msg) {
while (queue.size() == maxSize) {
try {
wait(); // 释放锁并等待
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
queue.add(msg);
notifyAll(); // 唤醒所有消费者
}
public synchronized String consume() {
while (queue.isEmpty()) {
try {
wait(); // 释放锁并等待
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
String msg = queue.poll();
notifyAll(); // 唤醒生产者
return msg;
}
}
关键机制:
wait()
时释放对象锁notify()
随机唤醒一个线程notifyAll()
唤醒所有等待线程while
循环检查条件(避免虚假唤醒)getClass()
:运行时类型识别// 获取类信息
Class<?> clazz = user.getClass();
// 应用场景
// 1. 反射操作
Method method = clazz.getMethod("getName");
// 2. 类型检查
if (clazz == User.class) {
// 精确类型匹配
}
clone()
:对象复制// 实现Cloneable接口
public class User implements Cloneable {
@Override
public User clone() {
try {
return (User) super.clone(); // 浅拷贝
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
// 深拷贝实现
public User deepClone() {
User cloned = this.clone();
cloned.address = this.address.clone(); // 嵌套对象也需克隆
return cloned;
}
finalize()
:资源清理的备选方案(已废弃)// Java 9+ 已标记为废弃
@Deprecated(since="9")
protected void finalize() throws Throwable {
// 非可靠资源清理
}
替代方案:
try-with-resources
AutoCloseable
接口wait()
的底层实现// HotSpot源码(jvm.cpp)
void ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) {
// 1. 获取对象监视器
ObjectMonitor* monitor = ObjectSynchronizer::inflate(THREAD, obj());
// 2. 加入等待集
monitor->AddWaiter(THREAD);
// 3. 释放锁
monitor->exit(true);
// 4. 线程挂起
os::sleep(THREAD, millis);
}
hashCode()
的生成策略// 默认实现(HotSpot)
public native int hashCode();
// 底层生成算法(通过-XX:hashCode=配置)
// 0: 随机数(默认)
// 1: 固定1(测试用)
// 2: 自增序列
// 3: 对象地址
// 4: 当前线程局部随机数
equals()
不遵守约定// 错误示例:违反对称性
class BrokenEquals {
private int id;
public boolean equals(Object o) {
// 允许与String比较
if (o instanceof String) {
return id == Integer.parseInt((String) o);
}
// ...
}
}
遵守五大契约:
x.equals(x) == true
x.equals(y) == y.equals(x)
x.equals(null) == false
wait()
不释放锁synchronized (lock) {
if (!condition) {
lock.wait(); // 正确:释放锁
}
}
// 错误:在同步块外调用
lock.wait(); // 抛出IllegalMonitorStateException
clone()
的浅拷贝问题User original = new User();
original.addFriend(new User("Bob"));
User cloned = original.clone();
cloned.getFriend().setName("Alice"); // 影响原对象!
解决方案:
public User(User other) {
this.id = other.id;
this.friends = new ArrayList<>();
for (User friend : other.friends) {
this.friends.add(new User(friend));
}
}
Pattern Matching
替代getClass()
// 传统方式
if (obj instanceof User) {
User user = (User) obj;
System.out.println(user.getName());
}
// Java 16+ 模式匹配
if (obj instanceof User user) {
System.out.println(user.getName());
}
Records
自动实现equals()
/hashCode()
// 自动生成规范实现
public record User(int id, String name, String email) {}
// 等效于:
public final class User {
private final int id;
private final String name;
private final String email;
// 自动生成构造器/equals/hashCode/toString
}
flowchart TD
Start[需要操作对象] --> Action{操作类型}
Action -->|对象打印| ToString[重写toString]
Action -->|对象比较| Equals[重写equals+hashCode]
Action -->|线程协作| Wait[wait/notify]
Action -->|对象复制| Clone[实现Cloneable]
Equals --> Collection{用于集合?}
Collection -->|是| HashCode[必须重写hashCode]
Collection -->|否| Check[按需重写]
Wait --> Sync[在synchronized块内调用]
Clone --> Deep{需要深拷贝?}
Deep -->|是| Custom[自定义深拷贝]
Deep -->|否| Super[super.clone]
性能提示:在超高频调用的场景(如每秒百万次),直接使用
System.identityHashCode()
比重写的hashCode()
快5倍以上,但需确保不依赖对象内容。